mirror of
https://github.com/beego/bee.git
synced 2025-06-14 23:50:39 +00:00
add vendor
This commit is contained in:
68
vendor/github.com/smartystreets/goconvey/convey/assertions.go
generated
vendored
Normal file
68
vendor/github.com/smartystreets/goconvey/convey/assertions.go
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
package convey
|
||||
|
||||
import "github.com/smartystreets/assertions"
|
||||
|
||||
var (
|
||||
ShouldEqual = assertions.ShouldEqual
|
||||
ShouldNotEqual = assertions.ShouldNotEqual
|
||||
ShouldAlmostEqual = assertions.ShouldAlmostEqual
|
||||
ShouldNotAlmostEqual = assertions.ShouldNotAlmostEqual
|
||||
ShouldResemble = assertions.ShouldResemble
|
||||
ShouldNotResemble = assertions.ShouldNotResemble
|
||||
ShouldPointTo = assertions.ShouldPointTo
|
||||
ShouldNotPointTo = assertions.ShouldNotPointTo
|
||||
ShouldBeNil = assertions.ShouldBeNil
|
||||
ShouldNotBeNil = assertions.ShouldNotBeNil
|
||||
ShouldBeTrue = assertions.ShouldBeTrue
|
||||
ShouldBeFalse = assertions.ShouldBeFalse
|
||||
ShouldBeZeroValue = assertions.ShouldBeZeroValue
|
||||
|
||||
ShouldBeGreaterThan = assertions.ShouldBeGreaterThan
|
||||
ShouldBeGreaterThanOrEqualTo = assertions.ShouldBeGreaterThanOrEqualTo
|
||||
ShouldBeLessThan = assertions.ShouldBeLessThan
|
||||
ShouldBeLessThanOrEqualTo = assertions.ShouldBeLessThanOrEqualTo
|
||||
ShouldBeBetween = assertions.ShouldBeBetween
|
||||
ShouldNotBeBetween = assertions.ShouldNotBeBetween
|
||||
ShouldBeBetweenOrEqual = assertions.ShouldBeBetweenOrEqual
|
||||
ShouldNotBeBetweenOrEqual = assertions.ShouldNotBeBetweenOrEqual
|
||||
|
||||
ShouldContain = assertions.ShouldContain
|
||||
ShouldNotContain = assertions.ShouldNotContain
|
||||
ShouldContainKey = assertions.ShouldContainKey
|
||||
ShouldNotContainKey = assertions.ShouldNotContainKey
|
||||
ShouldBeIn = assertions.ShouldBeIn
|
||||
ShouldNotBeIn = assertions.ShouldNotBeIn
|
||||
ShouldBeEmpty = assertions.ShouldBeEmpty
|
||||
ShouldNotBeEmpty = assertions.ShouldNotBeEmpty
|
||||
ShouldHaveLength = assertions.ShouldHaveLength
|
||||
|
||||
ShouldStartWith = assertions.ShouldStartWith
|
||||
ShouldNotStartWith = assertions.ShouldNotStartWith
|
||||
ShouldEndWith = assertions.ShouldEndWith
|
||||
ShouldNotEndWith = assertions.ShouldNotEndWith
|
||||
ShouldBeBlank = assertions.ShouldBeBlank
|
||||
ShouldNotBeBlank = assertions.ShouldNotBeBlank
|
||||
ShouldContainSubstring = assertions.ShouldContainSubstring
|
||||
ShouldNotContainSubstring = assertions.ShouldNotContainSubstring
|
||||
|
||||
ShouldPanic = assertions.ShouldPanic
|
||||
ShouldNotPanic = assertions.ShouldNotPanic
|
||||
ShouldPanicWith = assertions.ShouldPanicWith
|
||||
ShouldNotPanicWith = assertions.ShouldNotPanicWith
|
||||
|
||||
ShouldHaveSameTypeAs = assertions.ShouldHaveSameTypeAs
|
||||
ShouldNotHaveSameTypeAs = assertions.ShouldNotHaveSameTypeAs
|
||||
ShouldImplement = assertions.ShouldImplement
|
||||
ShouldNotImplement = assertions.ShouldNotImplement
|
||||
|
||||
ShouldHappenBefore = assertions.ShouldHappenBefore
|
||||
ShouldHappenOnOrBefore = assertions.ShouldHappenOnOrBefore
|
||||
ShouldHappenAfter = assertions.ShouldHappenAfter
|
||||
ShouldHappenOnOrAfter = assertions.ShouldHappenOnOrAfter
|
||||
ShouldHappenBetween = assertions.ShouldHappenBetween
|
||||
ShouldHappenOnOrBetween = assertions.ShouldHappenOnOrBetween
|
||||
ShouldNotHappenOnOrBetween = assertions.ShouldNotHappenOnOrBetween
|
||||
ShouldHappenWithin = assertions.ShouldHappenWithin
|
||||
ShouldNotHappenWithin = assertions.ShouldNotHappenWithin
|
||||
ShouldBeChronological = assertions.ShouldBeChronological
|
||||
)
|
272
vendor/github.com/smartystreets/goconvey/convey/context.go
generated
vendored
Normal file
272
vendor/github.com/smartystreets/goconvey/convey/context.go
generated
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
package convey
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jtolds/gls"
|
||||
"github.com/smartystreets/goconvey/convey/reporting"
|
||||
)
|
||||
|
||||
type conveyErr struct {
|
||||
fmt string
|
||||
params []interface{}
|
||||
}
|
||||
|
||||
func (e *conveyErr) Error() string {
|
||||
return fmt.Sprintf(e.fmt, e.params...)
|
||||
}
|
||||
|
||||
func conveyPanic(fmt string, params ...interface{}) {
|
||||
panic(&conveyErr{fmt, params})
|
||||
}
|
||||
|
||||
const (
|
||||
missingGoTest = `Top-level calls to Convey(...) need a reference to the *testing.T.
|
||||
Hint: Convey("description here", t, func() { /* notice that the second argument was the *testing.T (t)! */ }) `
|
||||
extraGoTest = `Only the top-level call to Convey(...) needs a reference to the *testing.T.`
|
||||
noStackContext = "Convey operation made without context on goroutine stack.\n" +
|
||||
"Hint: Perhaps you meant to use `Convey(..., func(c C){...})` ?"
|
||||
differentConveySituations = "Different set of Convey statements on subsequent pass!\nDid not expect %#v."
|
||||
multipleIdenticalConvey = "Multiple convey suites with identical names: %#v"
|
||||
)
|
||||
|
||||
const (
|
||||
failureHalt = "___FAILURE_HALT___"
|
||||
|
||||
nodeKey = "node"
|
||||
)
|
||||
|
||||
///////////////////////////////// Stack Context /////////////////////////////////
|
||||
|
||||
func getCurrentContext() *context {
|
||||
ctx, ok := ctxMgr.GetValue(nodeKey)
|
||||
if ok {
|
||||
return ctx.(*context)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func mustGetCurrentContext() *context {
|
||||
ctx := getCurrentContext()
|
||||
if ctx == nil {
|
||||
conveyPanic(noStackContext)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
//////////////////////////////////// Context ////////////////////////////////////
|
||||
|
||||
// context magically handles all coordination of Convey's and So assertions.
|
||||
//
|
||||
// It is tracked on the stack as goroutine-local-storage with the gls package,
|
||||
// or explicitly if the user decides to call convey like:
|
||||
//
|
||||
// Convey(..., func(c C) {
|
||||
// c.So(...)
|
||||
// })
|
||||
//
|
||||
// This implements the `C` interface.
|
||||
type context struct {
|
||||
reporter reporting.Reporter
|
||||
|
||||
children map[string]*context
|
||||
|
||||
resets []func()
|
||||
|
||||
executedOnce bool
|
||||
expectChildRun *bool
|
||||
complete bool
|
||||
|
||||
focus bool
|
||||
failureMode FailureMode
|
||||
}
|
||||
|
||||
// rootConvey is the main entry point to a test suite. This is called when
|
||||
// there's no context in the stack already, and items must contain a `t` object,
|
||||
// or this panics.
|
||||
func rootConvey(items ...interface{}) {
|
||||
entry := discover(items)
|
||||
|
||||
if entry.Test == nil {
|
||||
conveyPanic(missingGoTest)
|
||||
}
|
||||
|
||||
expectChildRun := true
|
||||
ctx := &context{
|
||||
reporter: buildReporter(),
|
||||
|
||||
children: make(map[string]*context),
|
||||
|
||||
expectChildRun: &expectChildRun,
|
||||
|
||||
focus: entry.Focus,
|
||||
failureMode: defaultFailureMode.combine(entry.FailMode),
|
||||
}
|
||||
ctxMgr.SetValues(gls.Values{nodeKey: ctx}, func() {
|
||||
ctx.reporter.BeginStory(reporting.NewStoryReport(entry.Test))
|
||||
defer ctx.reporter.EndStory()
|
||||
|
||||
for ctx.shouldVisit() {
|
||||
ctx.conveyInner(entry.Situation, entry.Func)
|
||||
expectChildRun = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//////////////////////////////////// Methods ////////////////////////////////////
|
||||
|
||||
func (ctx *context) SkipConvey(items ...interface{}) {
|
||||
ctx.Convey(items, skipConvey)
|
||||
}
|
||||
|
||||
func (ctx *context) FocusConvey(items ...interface{}) {
|
||||
ctx.Convey(items, focusConvey)
|
||||
}
|
||||
|
||||
func (ctx *context) Convey(items ...interface{}) {
|
||||
entry := discover(items)
|
||||
|
||||
// we're a branch, or leaf (on the wind)
|
||||
if entry.Test != nil {
|
||||
conveyPanic(extraGoTest)
|
||||
}
|
||||
if ctx.focus && !entry.Focus {
|
||||
return
|
||||
}
|
||||
|
||||
var inner_ctx *context
|
||||
if ctx.executedOnce {
|
||||
var ok bool
|
||||
inner_ctx, ok = ctx.children[entry.Situation]
|
||||
if !ok {
|
||||
conveyPanic(differentConveySituations, entry.Situation)
|
||||
}
|
||||
} else {
|
||||
if _, ok := ctx.children[entry.Situation]; ok {
|
||||
conveyPanic(multipleIdenticalConvey, entry.Situation)
|
||||
}
|
||||
inner_ctx = &context{
|
||||
reporter: ctx.reporter,
|
||||
|
||||
children: make(map[string]*context),
|
||||
|
||||
expectChildRun: ctx.expectChildRun,
|
||||
|
||||
focus: entry.Focus,
|
||||
failureMode: ctx.failureMode.combine(entry.FailMode),
|
||||
}
|
||||
ctx.children[entry.Situation] = inner_ctx
|
||||
}
|
||||
|
||||
if inner_ctx.shouldVisit() {
|
||||
ctxMgr.SetValues(gls.Values{nodeKey: inner_ctx}, func() {
|
||||
inner_ctx.conveyInner(entry.Situation, entry.Func)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *context) SkipSo(stuff ...interface{}) {
|
||||
ctx.assertionReport(reporting.NewSkipReport())
|
||||
}
|
||||
|
||||
func (ctx *context) So(actual interface{}, assert assertion, expected ...interface{}) {
|
||||
if result := assert(actual, expected...); result == assertionSuccess {
|
||||
ctx.assertionReport(reporting.NewSuccessReport())
|
||||
} else {
|
||||
ctx.assertionReport(reporting.NewFailureReport(result))
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *context) Reset(action func()) {
|
||||
/* TODO: Failure mode configuration */
|
||||
ctx.resets = append(ctx.resets, action)
|
||||
}
|
||||
|
||||
func (ctx *context) Print(items ...interface{}) (int, error) {
|
||||
fmt.Fprint(ctx.reporter, items...)
|
||||
return fmt.Print(items...)
|
||||
}
|
||||
|
||||
func (ctx *context) Println(items ...interface{}) (int, error) {
|
||||
fmt.Fprintln(ctx.reporter, items...)
|
||||
return fmt.Println(items...)
|
||||
}
|
||||
|
||||
func (ctx *context) Printf(format string, items ...interface{}) (int, error) {
|
||||
fmt.Fprintf(ctx.reporter, format, items...)
|
||||
return fmt.Printf(format, items...)
|
||||
}
|
||||
|
||||
//////////////////////////////////// Private ////////////////////////////////////
|
||||
|
||||
// shouldVisit returns true iff we should traverse down into a Convey. Note
|
||||
// that just because we don't traverse a Convey this time, doesn't mean that
|
||||
// we may not traverse it on a subsequent pass.
|
||||
func (c *context) shouldVisit() bool {
|
||||
return !c.complete && *c.expectChildRun
|
||||
}
|
||||
|
||||
// conveyInner is the function which actually executes the user's anonymous test
|
||||
// function body. At this point, Convey or RootConvey has decided that this
|
||||
// function should actually run.
|
||||
func (ctx *context) conveyInner(situation string, f func(C)) {
|
||||
// Record/Reset state for next time.
|
||||
defer func() {
|
||||
ctx.executedOnce = true
|
||||
|
||||
// This is only needed at the leaves, but there's no harm in also setting it
|
||||
// when returning from branch Convey's
|
||||
*ctx.expectChildRun = false
|
||||
}()
|
||||
|
||||
// Set up+tear down our scope for the reporter
|
||||
ctx.reporter.Enter(reporting.NewScopeReport(situation))
|
||||
defer ctx.reporter.Exit()
|
||||
|
||||
// Recover from any panics in f, and assign the `complete` status for this
|
||||
// node of the tree.
|
||||
defer func() {
|
||||
ctx.complete = true
|
||||
if problem := recover(); problem != nil {
|
||||
if problem, ok := problem.(*conveyErr); ok {
|
||||
panic(problem)
|
||||
}
|
||||
if problem != failureHalt {
|
||||
ctx.reporter.Report(reporting.NewErrorReport(problem))
|
||||
}
|
||||
} else {
|
||||
for _, child := range ctx.children {
|
||||
if !child.complete {
|
||||
ctx.complete = false
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Resets are registered as the `f` function executes, so nil them here.
|
||||
// All resets are run in registration order (FIFO).
|
||||
ctx.resets = []func(){}
|
||||
defer func() {
|
||||
for _, r := range ctx.resets {
|
||||
// panics handled by the previous defer
|
||||
r()
|
||||
}
|
||||
}()
|
||||
|
||||
if f == nil {
|
||||
// if f is nil, this was either a Convey(..., nil), or a SkipConvey
|
||||
ctx.reporter.Report(reporting.NewSkipReport())
|
||||
} else {
|
||||
f(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// assertionReport is a helper for So and SkipSo which makes the report and
|
||||
// then possibly panics, depending on the current context's failureMode.
|
||||
func (ctx *context) assertionReport(r *reporting.AssertionResult) {
|
||||
ctx.reporter.Report(r)
|
||||
if r.Failure != "" && ctx.failureMode == FailureHalts {
|
||||
panic(failureHalt)
|
||||
}
|
||||
}
|
4
vendor/github.com/smartystreets/goconvey/convey/convey.goconvey
generated
vendored
Normal file
4
vendor/github.com/smartystreets/goconvey/convey/convey.goconvey
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
#ignore
|
||||
-timeout=1s
|
||||
#-covermode=count
|
||||
#-coverpkg=github.com/smartystreets/goconvey/convey,github.com/smartystreets/goconvey/convey/gotest,github.com/smartystreets/goconvey/convey/reporting
|
103
vendor/github.com/smartystreets/goconvey/convey/discovery.go
generated
vendored
Normal file
103
vendor/github.com/smartystreets/goconvey/convey/discovery.go
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
package convey
|
||||
|
||||
type actionSpecifier uint8
|
||||
|
||||
const (
|
||||
noSpecifier actionSpecifier = iota
|
||||
skipConvey
|
||||
focusConvey
|
||||
)
|
||||
|
||||
type suite struct {
|
||||
Situation string
|
||||
Test t
|
||||
Focus bool
|
||||
Func func(C) // nil means skipped
|
||||
FailMode FailureMode
|
||||
}
|
||||
|
||||
func newSuite(situation string, failureMode FailureMode, f func(C), test t, specifier actionSpecifier) *suite {
|
||||
ret := &suite{
|
||||
Situation: situation,
|
||||
Test: test,
|
||||
Func: f,
|
||||
FailMode: failureMode,
|
||||
}
|
||||
switch specifier {
|
||||
case skipConvey:
|
||||
ret.Func = nil
|
||||
case focusConvey:
|
||||
ret.Focus = true
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func discover(items []interface{}) *suite {
|
||||
name, items := parseName(items)
|
||||
test, items := parseGoTest(items)
|
||||
failure, items := parseFailureMode(items)
|
||||
action, items := parseAction(items)
|
||||
specifier, items := parseSpecifier(items)
|
||||
|
||||
if len(items) != 0 {
|
||||
conveyPanic(parseError)
|
||||
}
|
||||
|
||||
return newSuite(name, failure, action, test, specifier)
|
||||
}
|
||||
func item(items []interface{}) interface{} {
|
||||
if len(items) == 0 {
|
||||
conveyPanic(parseError)
|
||||
}
|
||||
return items[0]
|
||||
}
|
||||
func parseName(items []interface{}) (string, []interface{}) {
|
||||
if name, parsed := item(items).(string); parsed {
|
||||
return name, items[1:]
|
||||
}
|
||||
conveyPanic(parseError)
|
||||
panic("never get here")
|
||||
}
|
||||
func parseGoTest(items []interface{}) (t, []interface{}) {
|
||||
if test, parsed := item(items).(t); parsed {
|
||||
return test, items[1:]
|
||||
}
|
||||
return nil, items
|
||||
}
|
||||
func parseFailureMode(items []interface{}) (FailureMode, []interface{}) {
|
||||
if mode, parsed := item(items).(FailureMode); parsed {
|
||||
return mode, items[1:]
|
||||
}
|
||||
return FailureInherits, items
|
||||
}
|
||||
func parseAction(items []interface{}) (func(C), []interface{}) {
|
||||
switch x := item(items).(type) {
|
||||
case nil:
|
||||
return nil, items[1:]
|
||||
case func(C):
|
||||
return x, items[1:]
|
||||
case func():
|
||||
return func(C) { x() }, items[1:]
|
||||
}
|
||||
conveyPanic(parseError)
|
||||
panic("never get here")
|
||||
}
|
||||
func parseSpecifier(items []interface{}) (actionSpecifier, []interface{}) {
|
||||
if len(items) == 0 {
|
||||
return noSpecifier, items
|
||||
}
|
||||
if spec, ok := items[0].(actionSpecifier); ok {
|
||||
return spec, items[1:]
|
||||
}
|
||||
conveyPanic(parseError)
|
||||
panic("never get here")
|
||||
}
|
||||
|
||||
// This interface allows us to pass the *testing.T struct
|
||||
// throughout the internals of this package without ever
|
||||
// having to import the "testing" package.
|
||||
type t interface {
|
||||
Fail()
|
||||
}
|
||||
|
||||
const parseError = "You must provide a name (string), then a *testing.T (if in outermost scope), an optional FailureMode, and then an action (func())."
|
218
vendor/github.com/smartystreets/goconvey/convey/doc.go
generated
vendored
Normal file
218
vendor/github.com/smartystreets/goconvey/convey/doc.go
generated
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
// Package convey contains all of the public-facing entry points to this project.
|
||||
// This means that it should never be required of the user to import any other
|
||||
// packages from this project as they serve internal purposes.
|
||||
package convey
|
||||
|
||||
import "github.com/smartystreets/goconvey/convey/reporting"
|
||||
|
||||
////////////////////////////////// suite //////////////////////////////////
|
||||
|
||||
// C is the Convey context which you can optionally obtain in your action
|
||||
// by calling Convey like:
|
||||
//
|
||||
// Convey(..., func(c C) {
|
||||
// ...
|
||||
// })
|
||||
//
|
||||
// See the documentation on Convey for more details.
|
||||
//
|
||||
// All methods in this context behave identically to the global functions of the
|
||||
// same name in this package.
|
||||
type C interface {
|
||||
Convey(items ...interface{})
|
||||
SkipConvey(items ...interface{})
|
||||
FocusConvey(items ...interface{})
|
||||
|
||||
So(actual interface{}, assert assertion, expected ...interface{})
|
||||
SkipSo(stuff ...interface{})
|
||||
|
||||
Reset(action func())
|
||||
|
||||
Println(items ...interface{}) (int, error)
|
||||
Print(items ...interface{}) (int, error)
|
||||
Printf(format string, items ...interface{}) (int, error)
|
||||
}
|
||||
|
||||
// Convey is the method intended for use when declaring the scopes of
|
||||
// a specification. Each scope has a description and a func() which may contain
|
||||
// other calls to Convey(), Reset() or Should-style assertions. Convey calls can
|
||||
// be nested as far as you see fit.
|
||||
//
|
||||
// IMPORTANT NOTE: The top-level Convey() within a Test method
|
||||
// must conform to the following signature:
|
||||
//
|
||||
// Convey(description string, t *testing.T, action func())
|
||||
//
|
||||
// All other calls should look like this (no need to pass in *testing.T):
|
||||
//
|
||||
// Convey(description string, action func())
|
||||
//
|
||||
// Don't worry, goconvey will panic if you get it wrong so you can fix it.
|
||||
//
|
||||
// Additionally, you may explicitly obtain access to the Convey context by doing:
|
||||
//
|
||||
// Convey(description string, action func(c C))
|
||||
//
|
||||
// You may need to do this if you want to pass the context through to a
|
||||
// goroutine, or to close over the context in a handler to a library which
|
||||
// calls your handler in a goroutine (httptest comes to mind).
|
||||
//
|
||||
// All Convey()-blocks also accept an optional parameter of FailureMode which sets
|
||||
// how goconvey should treat failures for So()-assertions in the block and
|
||||
// nested blocks. See the constants in this file for the available options.
|
||||
//
|
||||
// By default it will inherit from its parent block and the top-level blocks
|
||||
// default to the FailureHalts setting.
|
||||
//
|
||||
// This parameter is inserted before the block itself:
|
||||
//
|
||||
// Convey(description string, t *testing.T, mode FailureMode, action func())
|
||||
// Convey(description string, mode FailureMode, action func())
|
||||
//
|
||||
// See the examples package for, well, examples.
|
||||
func Convey(items ...interface{}) {
|
||||
if ctx := getCurrentContext(); ctx == nil {
|
||||
rootConvey(items...)
|
||||
} else {
|
||||
ctx.Convey(items...)
|
||||
}
|
||||
}
|
||||
|
||||
// SkipConvey is analagous to Convey except that the scope is not executed
|
||||
// (which means that child scopes defined within this scope are not run either).
|
||||
// The reporter will be notified that this step was skipped.
|
||||
func SkipConvey(items ...interface{}) {
|
||||
Convey(append(items, skipConvey)...)
|
||||
}
|
||||
|
||||
// FocusConvey is has the inverse effect of SkipConvey. If the top-level
|
||||
// Convey is changed to `FocusConvey`, only nested scopes that are defined
|
||||
// with FocusConvey will be run. The rest will be ignored completely. This
|
||||
// is handy when debugging a large suite that runs a misbehaving function
|
||||
// repeatedly as you can disable all but one of that function
|
||||
// without swaths of `SkipConvey` calls, just a targeted chain of calls
|
||||
// to FocusConvey.
|
||||
func FocusConvey(items ...interface{}) {
|
||||
Convey(append(items, focusConvey)...)
|
||||
}
|
||||
|
||||
// Reset registers a cleanup function to be run after each Convey()
|
||||
// in the same scope. See the examples package for a simple use case.
|
||||
func Reset(action func()) {
|
||||
mustGetCurrentContext().Reset(action)
|
||||
}
|
||||
|
||||
/////////////////////////////////// Assertions ///////////////////////////////////
|
||||
|
||||
// assertion is an alias for a function with a signature that the convey.So()
|
||||
// method can handle. Any future or custom assertions should conform to this
|
||||
// method signature. The return value should be an empty string if the assertion
|
||||
// passes and a well-formed failure message if not.
|
||||
type assertion func(actual interface{}, expected ...interface{}) string
|
||||
|
||||
const assertionSuccess = ""
|
||||
|
||||
// So is the means by which assertions are made against the system under test.
|
||||
// The majority of exported names in the assertions package begin with the word
|
||||
// 'Should' and describe how the first argument (actual) should compare with any
|
||||
// of the final (expected) arguments. How many final arguments are accepted
|
||||
// depends on the particular assertion that is passed in as the assert argument.
|
||||
// See the examples package for use cases and the assertions package for
|
||||
// documentation on specific assertion methods. A failing assertion will
|
||||
// cause t.Fail() to be invoked--you should never call this method (or other
|
||||
// failure-inducing methods) in your test code. Leave that to GoConvey.
|
||||
func So(actual interface{}, assert assertion, expected ...interface{}) {
|
||||
mustGetCurrentContext().So(actual, assert, expected...)
|
||||
}
|
||||
|
||||
// SkipSo is analagous to So except that the assertion that would have been passed
|
||||
// to So is not executed and the reporter is notified that the assertion was skipped.
|
||||
func SkipSo(stuff ...interface{}) {
|
||||
mustGetCurrentContext().SkipSo()
|
||||
}
|
||||
|
||||
// FailureMode is a type which determines how the So() blocks should fail
|
||||
// if their assertion fails. See constants further down for acceptable values
|
||||
type FailureMode string
|
||||
|
||||
const (
|
||||
|
||||
// FailureContinues is a failure mode which prevents failing
|
||||
// So()-assertions from halting Convey-block execution, instead
|
||||
// allowing the test to continue past failing So()-assertions.
|
||||
FailureContinues FailureMode = "continue"
|
||||
|
||||
// FailureHalts is the default setting for a top-level Convey()-block
|
||||
// and will cause all failing So()-assertions to halt further execution
|
||||
// in that test-arm and continue on to the next arm.
|
||||
FailureHalts FailureMode = "halt"
|
||||
|
||||
// FailureInherits is the default setting for failure-mode, it will
|
||||
// default to the failure-mode of the parent block. You should never
|
||||
// need to specify this mode in your tests..
|
||||
FailureInherits FailureMode = "inherits"
|
||||
)
|
||||
|
||||
func (f FailureMode) combine(other FailureMode) FailureMode {
|
||||
if other == FailureInherits {
|
||||
return f
|
||||
}
|
||||
return other
|
||||
}
|
||||
|
||||
var defaultFailureMode FailureMode = FailureHalts
|
||||
|
||||
// SetDefaultFailureMode allows you to specify the default failure mode
|
||||
// for all Convey blocks. It is meant to be used in an init function to
|
||||
// allow the default mode to be changdd across all tests for an entire packgae
|
||||
// but it can be used anywhere.
|
||||
func SetDefaultFailureMode(mode FailureMode) {
|
||||
if mode == FailureContinues || mode == FailureHalts {
|
||||
defaultFailureMode = mode
|
||||
} else {
|
||||
panic("You may only use the constants named 'FailureContinues' and 'FailureHalts' as default failure modes.")
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////// Print functions ////////////////////////////////////
|
||||
|
||||
// Print is analogous to fmt.Print (and it even calls fmt.Print). It ensures that
|
||||
// output is aligned with the corresponding scopes in the web UI.
|
||||
func Print(items ...interface{}) (written int, err error) {
|
||||
return mustGetCurrentContext().Print(items...)
|
||||
}
|
||||
|
||||
// Print is analogous to fmt.Println (and it even calls fmt.Println). It ensures that
|
||||
// output is aligned with the corresponding scopes in the web UI.
|
||||
func Println(items ...interface{}) (written int, err error) {
|
||||
return mustGetCurrentContext().Println(items...)
|
||||
}
|
||||
|
||||
// Print is analogous to fmt.Printf (and it even calls fmt.Printf). It ensures that
|
||||
// output is aligned with the corresponding scopes in the web UI.
|
||||
func Printf(format string, items ...interface{}) (written int, err error) {
|
||||
return mustGetCurrentContext().Printf(format, items...)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// SuppressConsoleStatistics prevents automatic printing of console statistics.
|
||||
// Calling PrintConsoleStatistics explicitly will force printing of statistics.
|
||||
func SuppressConsoleStatistics() {
|
||||
reporting.SuppressConsoleStatistics()
|
||||
}
|
||||
|
||||
// ConsoleStatistics may be called at any time to print assertion statistics.
|
||||
// Generally, the best place to do this would be in a TestMain function,
|
||||
// after all tests have been run. Something like this:
|
||||
//
|
||||
// func TestMain(m *testing.M) {
|
||||
// convey.SuppressConsoleStatistics()
|
||||
// result := m.Run()
|
||||
// convey.PrintConsoleStatistics()
|
||||
// os.Exit(result)
|
||||
// }
|
||||
//
|
||||
func PrintConsoleStatistics() {
|
||||
reporting.PrintConsoleStatistics()
|
||||
}
|
28
vendor/github.com/smartystreets/goconvey/convey/gotest/utils.go
generated
vendored
Normal file
28
vendor/github.com/smartystreets/goconvey/convey/gotest/utils.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// Package gotest contains internal functionality. Although this package
|
||||
// contains one or more exported names it is not intended for public
|
||||
// consumption. See the examples package for how to use this project.
|
||||
package gotest
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ResolveExternalCaller() (file string, line int, name string) {
|
||||
var caller_id uintptr
|
||||
callers := runtime.Callers(0, callStack)
|
||||
|
||||
for x := 0; x < callers; x++ {
|
||||
caller_id, file, line, _ = runtime.Caller(x)
|
||||
if strings.HasSuffix(file, "_test.go") || strings.HasSuffix(file, "_tests.go") {
|
||||
name = runtime.FuncForPC(caller_id).Name()
|
||||
return
|
||||
}
|
||||
}
|
||||
file, line, name = "<unkown file>", -1, "<unknown name>"
|
||||
return // panic?
|
||||
}
|
||||
|
||||
const maxStackDepth = 100 // This had better be enough...
|
||||
|
||||
var callStack []uintptr = make([]uintptr, maxStackDepth, maxStackDepth)
|
81
vendor/github.com/smartystreets/goconvey/convey/init.go
generated
vendored
Normal file
81
vendor/github.com/smartystreets/goconvey/convey/init.go
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
package convey
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"github.com/jtolds/gls"
|
||||
"github.com/smartystreets/assertions"
|
||||
"github.com/smartystreets/goconvey/convey/reporting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
assertions.GoConveyMode(true)
|
||||
|
||||
declareFlags()
|
||||
|
||||
ctxMgr = gls.NewContextManager()
|
||||
}
|
||||
|
||||
func declareFlags() {
|
||||
flag.BoolVar(&json, "json", false, "When true, emits results in JSON blocks. Default: 'false'")
|
||||
flag.BoolVar(&silent, "silent", false, "When true, all output from GoConvey is suppressed.")
|
||||
flag.BoolVar(&story, "story", false, "When true, emits story output, otherwise emits dot output. When not provided, this flag mirros the value of the '-test.v' flag")
|
||||
|
||||
if noStoryFlagProvided() {
|
||||
story = verboseEnabled
|
||||
}
|
||||
|
||||
// FYI: flag.Parse() is called from the testing package.
|
||||
}
|
||||
|
||||
func noStoryFlagProvided() bool {
|
||||
return !story && !storyDisabled
|
||||
}
|
||||
|
||||
func buildReporter() reporting.Reporter {
|
||||
selectReporter := os.Getenv("GOCONVEY_REPORTER")
|
||||
|
||||
switch {
|
||||
case testReporter != nil:
|
||||
return testReporter
|
||||
case json || selectReporter == "json":
|
||||
return reporting.BuildJsonReporter()
|
||||
case silent || selectReporter == "silent":
|
||||
return reporting.BuildSilentReporter()
|
||||
case selectReporter == "dot":
|
||||
// Story is turned on when verbose is set, so we need to check for dot reporter first.
|
||||
return reporting.BuildDotReporter()
|
||||
case story || selectReporter == "story":
|
||||
return reporting.BuildStoryReporter()
|
||||
default:
|
||||
return reporting.BuildDotReporter()
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
ctxMgr *gls.ContextManager
|
||||
|
||||
// only set by internal tests
|
||||
testReporter reporting.Reporter
|
||||
)
|
||||
|
||||
var (
|
||||
json bool
|
||||
silent bool
|
||||
story bool
|
||||
|
||||
verboseEnabled = flagFound("-test.v=true")
|
||||
storyDisabled = flagFound("-story=false")
|
||||
)
|
||||
|
||||
// flagFound parses the command line args manually for flags defined in other
|
||||
// packages. Like the '-v' flag from the "testing" package, for instance.
|
||||
func flagFound(flagValue string) bool {
|
||||
for _, arg := range os.Args {
|
||||
if arg == flagValue {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
15
vendor/github.com/smartystreets/goconvey/convey/nilReporter.go
generated
vendored
Normal file
15
vendor/github.com/smartystreets/goconvey/convey/nilReporter.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
package convey
|
||||
|
||||
import (
|
||||
"github.com/smartystreets/goconvey/convey/reporting"
|
||||
)
|
||||
|
||||
type nilReporter struct{}
|
||||
|
||||
func (self *nilReporter) BeginStory(story *reporting.StoryReport) {}
|
||||
func (self *nilReporter) Enter(scope *reporting.ScopeReport) {}
|
||||
func (self *nilReporter) Report(report *reporting.AssertionResult) {}
|
||||
func (self *nilReporter) Exit() {}
|
||||
func (self *nilReporter) EndStory() {}
|
||||
func (self *nilReporter) Write(p []byte) (int, error) { return len(p), nil }
|
||||
func newNilReporter() *nilReporter { return &nilReporter{} }
|
16
vendor/github.com/smartystreets/goconvey/convey/reporting/console.go
generated
vendored
Normal file
16
vendor/github.com/smartystreets/goconvey/convey/reporting/console.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type console struct{}
|
||||
|
||||
func (self *console) Write(p []byte) (n int, err error) {
|
||||
return fmt.Print(string(p))
|
||||
}
|
||||
|
||||
func NewConsole() io.Writer {
|
||||
return new(console)
|
||||
}
|
5
vendor/github.com/smartystreets/goconvey/convey/reporting/doc.go
generated
vendored
Normal file
5
vendor/github.com/smartystreets/goconvey/convey/reporting/doc.go
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
// Package reporting contains internal functionality related
|
||||
// to console reporting and output. Although this package has
|
||||
// exported names is not intended for public consumption. See the
|
||||
// examples package for how to use this project.
|
||||
package reporting
|
40
vendor/github.com/smartystreets/goconvey/convey/reporting/dot.go
generated
vendored
Normal file
40
vendor/github.com/smartystreets/goconvey/convey/reporting/dot.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
package reporting
|
||||
|
||||
import "fmt"
|
||||
|
||||
type dot struct{ out *Printer }
|
||||
|
||||
func (self *dot) BeginStory(story *StoryReport) {}
|
||||
|
||||
func (self *dot) Enter(scope *ScopeReport) {}
|
||||
|
||||
func (self *dot) Report(report *AssertionResult) {
|
||||
if report.Error != nil {
|
||||
fmt.Print(redColor)
|
||||
self.out.Insert(dotError)
|
||||
} else if report.Failure != "" {
|
||||
fmt.Print(yellowColor)
|
||||
self.out.Insert(dotFailure)
|
||||
} else if report.Skipped {
|
||||
fmt.Print(yellowColor)
|
||||
self.out.Insert(dotSkip)
|
||||
} else {
|
||||
fmt.Print(greenColor)
|
||||
self.out.Insert(dotSuccess)
|
||||
}
|
||||
fmt.Print(resetColor)
|
||||
}
|
||||
|
||||
func (self *dot) Exit() {}
|
||||
|
||||
func (self *dot) EndStory() {}
|
||||
|
||||
func (self *dot) Write(content []byte) (written int, err error) {
|
||||
return len(content), nil // no-op
|
||||
}
|
||||
|
||||
func NewDotReporter(out *Printer) *dot {
|
||||
self := new(dot)
|
||||
self.out = out
|
||||
return self
|
||||
}
|
33
vendor/github.com/smartystreets/goconvey/convey/reporting/gotest.go
generated
vendored
Normal file
33
vendor/github.com/smartystreets/goconvey/convey/reporting/gotest.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
package reporting
|
||||
|
||||
type gotestReporter struct{ test T }
|
||||
|
||||
func (self *gotestReporter) BeginStory(story *StoryReport) {
|
||||
self.test = story.Test
|
||||
}
|
||||
|
||||
func (self *gotestReporter) Enter(scope *ScopeReport) {}
|
||||
|
||||
func (self *gotestReporter) Report(r *AssertionResult) {
|
||||
if !passed(r) {
|
||||
self.test.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *gotestReporter) Exit() {}
|
||||
|
||||
func (self *gotestReporter) EndStory() {
|
||||
self.test = nil
|
||||
}
|
||||
|
||||
func (self *gotestReporter) Write(content []byte) (written int, err error) {
|
||||
return len(content), nil // no-op
|
||||
}
|
||||
|
||||
func NewGoTestReporter() *gotestReporter {
|
||||
return new(gotestReporter)
|
||||
}
|
||||
|
||||
func passed(r *AssertionResult) bool {
|
||||
return r.Error == nil && r.Failure == ""
|
||||
}
|
97
vendor/github.com/smartystreets/goconvey/convey/reporting/init.go
generated
vendored
Normal file
97
vendor/github.com/smartystreets/goconvey/convey/reporting/init.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if !isXterm() {
|
||||
monochrome()
|
||||
}
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
success, failure, error_ = dotSuccess, dotFailure, dotError
|
||||
}
|
||||
}
|
||||
|
||||
func BuildJsonReporter() Reporter {
|
||||
out := NewPrinter(NewConsole())
|
||||
return NewReporters(
|
||||
NewGoTestReporter(),
|
||||
NewJsonReporter(out))
|
||||
}
|
||||
func BuildDotReporter() Reporter {
|
||||
out := NewPrinter(NewConsole())
|
||||
return NewReporters(
|
||||
NewGoTestReporter(),
|
||||
NewDotReporter(out),
|
||||
NewProblemReporter(out),
|
||||
consoleStatistics)
|
||||
}
|
||||
func BuildStoryReporter() Reporter {
|
||||
out := NewPrinter(NewConsole())
|
||||
return NewReporters(
|
||||
NewGoTestReporter(),
|
||||
NewStoryReporter(out),
|
||||
NewProblemReporter(out),
|
||||
consoleStatistics)
|
||||
}
|
||||
func BuildSilentReporter() Reporter {
|
||||
out := NewPrinter(NewConsole())
|
||||
return NewReporters(
|
||||
NewGoTestReporter(),
|
||||
NewSilentProblemReporter(out))
|
||||
}
|
||||
|
||||
var (
|
||||
newline = "\n"
|
||||
success = "✔"
|
||||
failure = "✘"
|
||||
error_ = "🔥"
|
||||
skip = "⚠"
|
||||
dotSuccess = "."
|
||||
dotFailure = "x"
|
||||
dotError = "E"
|
||||
dotSkip = "S"
|
||||
errorTemplate = "* %s \nLine %d: - %v \n%s\n"
|
||||
failureTemplate = "* %s \nLine %d:\n%s\n"
|
||||
)
|
||||
|
||||
var (
|
||||
greenColor = "\033[32m"
|
||||
yellowColor = "\033[33m"
|
||||
redColor = "\033[31m"
|
||||
resetColor = "\033[0m"
|
||||
)
|
||||
|
||||
var consoleStatistics = NewStatisticsReporter(NewPrinter(NewConsole()))
|
||||
|
||||
func SuppressConsoleStatistics() { consoleStatistics.Suppress() }
|
||||
func PrintConsoleStatistics() { consoleStatistics.PrintSummary() }
|
||||
|
||||
// QuiteMode disables all console output symbols. This is only meant to be used
|
||||
// for tests that are internal to goconvey where the output is distracting or
|
||||
// otherwise not needed in the test output.
|
||||
func QuietMode() {
|
||||
success, failure, error_, skip, dotSuccess, dotFailure, dotError, dotSkip = "", "", "", "", "", "", "", ""
|
||||
}
|
||||
|
||||
func monochrome() {
|
||||
greenColor, yellowColor, redColor, resetColor = "", "", "", ""
|
||||
}
|
||||
|
||||
func isXterm() bool {
|
||||
env := fmt.Sprintf("%v", os.Environ())
|
||||
return strings.Contains(env, " TERM=isXterm") ||
|
||||
strings.Contains(env, " TERM=xterm")
|
||||
}
|
||||
|
||||
// This interface allows us to pass the *testing.T struct
|
||||
// throughout the internals of this tool without ever
|
||||
// having to import the "testing" package.
|
||||
type T interface {
|
||||
Fail()
|
||||
}
|
88
vendor/github.com/smartystreets/goconvey/convey/reporting/json.go
generated
vendored
Normal file
88
vendor/github.com/smartystreets/goconvey/convey/reporting/json.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
// TODO: under unit test
|
||||
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type JsonReporter struct {
|
||||
out *Printer
|
||||
currentKey []string
|
||||
current *ScopeResult
|
||||
index map[string]*ScopeResult
|
||||
scopes []*ScopeResult
|
||||
}
|
||||
|
||||
func (self *JsonReporter) depth() int { return len(self.currentKey) }
|
||||
|
||||
func (self *JsonReporter) BeginStory(story *StoryReport) {}
|
||||
|
||||
func (self *JsonReporter) Enter(scope *ScopeReport) {
|
||||
self.currentKey = append(self.currentKey, scope.Title)
|
||||
ID := strings.Join(self.currentKey, "|")
|
||||
if _, found := self.index[ID]; !found {
|
||||
next := newScopeResult(scope.Title, self.depth(), scope.File, scope.Line)
|
||||
self.scopes = append(self.scopes, next)
|
||||
self.index[ID] = next
|
||||
}
|
||||
self.current = self.index[ID]
|
||||
}
|
||||
|
||||
func (self *JsonReporter) Report(report *AssertionResult) {
|
||||
self.current.Assertions = append(self.current.Assertions, report)
|
||||
}
|
||||
|
||||
func (self *JsonReporter) Exit() {
|
||||
self.currentKey = self.currentKey[:len(self.currentKey)-1]
|
||||
}
|
||||
|
||||
func (self *JsonReporter) EndStory() {
|
||||
self.report()
|
||||
self.reset()
|
||||
}
|
||||
func (self *JsonReporter) report() {
|
||||
scopes := []string{}
|
||||
for _, scope := range self.scopes {
|
||||
serialized, err := json.Marshal(scope)
|
||||
if err != nil {
|
||||
self.out.Println(jsonMarshalFailure)
|
||||
panic(err)
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
json.Indent(&buffer, serialized, "", " ")
|
||||
scopes = append(scopes, buffer.String())
|
||||
}
|
||||
self.out.Print(fmt.Sprintf("%s\n%s,\n%s\n", OpenJson, strings.Join(scopes, ","), CloseJson))
|
||||
}
|
||||
func (self *JsonReporter) reset() {
|
||||
self.scopes = []*ScopeResult{}
|
||||
self.index = map[string]*ScopeResult{}
|
||||
self.currentKey = nil
|
||||
}
|
||||
|
||||
func (self *JsonReporter) Write(content []byte) (written int, err error) {
|
||||
self.current.Output += string(content)
|
||||
return len(content), nil
|
||||
}
|
||||
|
||||
func NewJsonReporter(out *Printer) *JsonReporter {
|
||||
self := new(JsonReporter)
|
||||
self.out = out
|
||||
self.reset()
|
||||
return self
|
||||
}
|
||||
|
||||
const OpenJson = ">->->OPEN-JSON->->->" // "⌦"
|
||||
const CloseJson = "<-<-<-CLOSE-JSON<-<-<" // "⌫"
|
||||
const jsonMarshalFailure = `
|
||||
|
||||
GOCONVEY_JSON_MARSHALL_FAILURE: There was an error when attempting to convert test results to JSON.
|
||||
Please file a bug report and reference the code that caused this failure if possible.
|
||||
|
||||
Here's the panic:
|
||||
|
||||
`
|
57
vendor/github.com/smartystreets/goconvey/convey/reporting/printer.go
generated
vendored
Normal file
57
vendor/github.com/smartystreets/goconvey/convey/reporting/printer.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Printer struct {
|
||||
out io.Writer
|
||||
prefix string
|
||||
}
|
||||
|
||||
func (self *Printer) Println(message string, values ...interface{}) {
|
||||
formatted := self.format(message, values...) + newline
|
||||
self.out.Write([]byte(formatted))
|
||||
}
|
||||
|
||||
func (self *Printer) Print(message string, values ...interface{}) {
|
||||
formatted := self.format(message, values...)
|
||||
self.out.Write([]byte(formatted))
|
||||
}
|
||||
|
||||
func (self *Printer) Insert(text string) {
|
||||
self.out.Write([]byte(text))
|
||||
}
|
||||
|
||||
func (self *Printer) format(message string, values ...interface{}) string {
|
||||
var formatted string
|
||||
if len(values) == 0 {
|
||||
formatted = self.prefix + message
|
||||
} else {
|
||||
formatted = self.prefix + fmt.Sprintf(message, values...)
|
||||
}
|
||||
indented := strings.Replace(formatted, newline, newline+self.prefix, -1)
|
||||
return strings.TrimRight(indented, space)
|
||||
}
|
||||
|
||||
func (self *Printer) Indent() {
|
||||
self.prefix += pad
|
||||
}
|
||||
|
||||
func (self *Printer) Dedent() {
|
||||
if len(self.prefix) >= padLength {
|
||||
self.prefix = self.prefix[:len(self.prefix)-padLength]
|
||||
}
|
||||
}
|
||||
|
||||
func NewPrinter(out io.Writer) *Printer {
|
||||
self := new(Printer)
|
||||
self.out = out
|
||||
return self
|
||||
}
|
||||
|
||||
const space = " "
|
||||
const pad = space + space
|
||||
const padLength = len(pad)
|
80
vendor/github.com/smartystreets/goconvey/convey/reporting/problems.go
generated
vendored
Normal file
80
vendor/github.com/smartystreets/goconvey/convey/reporting/problems.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
package reporting
|
||||
|
||||
import "fmt"
|
||||
|
||||
type problem struct {
|
||||
silent bool
|
||||
out *Printer
|
||||
errors []*AssertionResult
|
||||
failures []*AssertionResult
|
||||
}
|
||||
|
||||
func (self *problem) BeginStory(story *StoryReport) {}
|
||||
|
||||
func (self *problem) Enter(scope *ScopeReport) {}
|
||||
|
||||
func (self *problem) Report(report *AssertionResult) {
|
||||
if report.Error != nil {
|
||||
self.errors = append(self.errors, report)
|
||||
} else if report.Failure != "" {
|
||||
self.failures = append(self.failures, report)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *problem) Exit() {}
|
||||
|
||||
func (self *problem) EndStory() {
|
||||
self.show(self.showErrors, redColor)
|
||||
self.show(self.showFailures, yellowColor)
|
||||
self.prepareForNextStory()
|
||||
}
|
||||
func (self *problem) show(display func(), color string) {
|
||||
if !self.silent {
|
||||
fmt.Print(color)
|
||||
}
|
||||
display()
|
||||
if !self.silent {
|
||||
fmt.Print(resetColor)
|
||||
}
|
||||
self.out.Dedent()
|
||||
}
|
||||
func (self *problem) showErrors() {
|
||||
for i, e := range self.errors {
|
||||
if i == 0 {
|
||||
self.out.Println("\nErrors:\n")
|
||||
self.out.Indent()
|
||||
}
|
||||
self.out.Println(errorTemplate, e.File, e.Line, e.Error, e.StackTrace)
|
||||
}
|
||||
}
|
||||
func (self *problem) showFailures() {
|
||||
for i, f := range self.failures {
|
||||
if i == 0 {
|
||||
self.out.Println("\nFailures:\n")
|
||||
self.out.Indent()
|
||||
}
|
||||
self.out.Println(failureTemplate, f.File, f.Line, f.Failure)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *problem) Write(content []byte) (written int, err error) {
|
||||
return len(content), nil // no-op
|
||||
}
|
||||
|
||||
func NewProblemReporter(out *Printer) *problem {
|
||||
self := new(problem)
|
||||
self.out = out
|
||||
self.prepareForNextStory()
|
||||
return self
|
||||
}
|
||||
|
||||
func NewSilentProblemReporter(out *Printer) *problem {
|
||||
self := NewProblemReporter(out)
|
||||
self.silent = true
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *problem) prepareForNextStory() {
|
||||
self.errors = []*AssertionResult{}
|
||||
self.failures = []*AssertionResult{}
|
||||
}
|
39
vendor/github.com/smartystreets/goconvey/convey/reporting/reporter.go
generated
vendored
Normal file
39
vendor/github.com/smartystreets/goconvey/convey/reporting/reporter.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
package reporting
|
||||
|
||||
import "io"
|
||||
|
||||
type Reporter interface {
|
||||
BeginStory(story *StoryReport)
|
||||
Enter(scope *ScopeReport)
|
||||
Report(r *AssertionResult)
|
||||
Exit()
|
||||
EndStory()
|
||||
io.Writer
|
||||
}
|
||||
|
||||
type reporters struct{ collection []Reporter }
|
||||
|
||||
func (self *reporters) BeginStory(s *StoryReport) { self.foreach(func(r Reporter) { r.BeginStory(s) }) }
|
||||
func (self *reporters) Enter(s *ScopeReport) { self.foreach(func(r Reporter) { r.Enter(s) }) }
|
||||
func (self *reporters) Report(a *AssertionResult) { self.foreach(func(r Reporter) { r.Report(a) }) }
|
||||
func (self *reporters) Exit() { self.foreach(func(r Reporter) { r.Exit() }) }
|
||||
func (self *reporters) EndStory() { self.foreach(func(r Reporter) { r.EndStory() }) }
|
||||
|
||||
func (self *reporters) Write(contents []byte) (written int, err error) {
|
||||
self.foreach(func(r Reporter) {
|
||||
written, err = r.Write(contents)
|
||||
})
|
||||
return written, err
|
||||
}
|
||||
|
||||
func (self *reporters) foreach(action func(Reporter)) {
|
||||
for _, r := range self.collection {
|
||||
action(r)
|
||||
}
|
||||
}
|
||||
|
||||
func NewReporters(collection ...Reporter) *reporters {
|
||||
self := new(reporters)
|
||||
self.collection = collection
|
||||
return self
|
||||
}
|
2
vendor/github.com/smartystreets/goconvey/convey/reporting/reporting.goconvey
generated
vendored
Normal file
2
vendor/github.com/smartystreets/goconvey/convey/reporting/reporting.goconvey
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
#ignore
|
||||
-timeout=1s
|
177
vendor/github.com/smartystreets/goconvey/convey/reporting/reports.go
generated
vendored
Normal file
177
vendor/github.com/smartystreets/goconvey/convey/reporting/reports.go
generated
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey/gotest"
|
||||
)
|
||||
|
||||
////////////////// ScopeReport ////////////////////
|
||||
|
||||
type ScopeReport struct {
|
||||
Title string
|
||||
File string
|
||||
Line int
|
||||
}
|
||||
|
||||
func NewScopeReport(title string) *ScopeReport {
|
||||
file, line, _ := gotest.ResolveExternalCaller()
|
||||
self := new(ScopeReport)
|
||||
self.Title = title
|
||||
self.File = file
|
||||
self.Line = line
|
||||
return self
|
||||
}
|
||||
|
||||
////////////////// ScopeResult ////////////////////
|
||||
|
||||
type ScopeResult struct {
|
||||
Title string
|
||||
File string
|
||||
Line int
|
||||
Depth int
|
||||
Assertions []*AssertionResult
|
||||
Output string
|
||||
}
|
||||
|
||||
func newScopeResult(title string, depth int, file string, line int) *ScopeResult {
|
||||
self := new(ScopeResult)
|
||||
self.Title = title
|
||||
self.Depth = depth
|
||||
self.File = file
|
||||
self.Line = line
|
||||
self.Assertions = []*AssertionResult{}
|
||||
return self
|
||||
}
|
||||
|
||||
/////////////////// StoryReport /////////////////////
|
||||
|
||||
type StoryReport struct {
|
||||
Test T
|
||||
Name string
|
||||
File string
|
||||
Line int
|
||||
}
|
||||
|
||||
func NewStoryReport(test T) *StoryReport {
|
||||
file, line, name := gotest.ResolveExternalCaller()
|
||||
name = removePackagePath(name)
|
||||
self := new(StoryReport)
|
||||
self.Test = test
|
||||
self.Name = name
|
||||
self.File = file
|
||||
self.Line = line
|
||||
return self
|
||||
}
|
||||
|
||||
// name comes in looking like "github.com/smartystreets/goconvey/examples.TestName".
|
||||
// We only want the stuff after the last '.', which is the name of the test function.
|
||||
func removePackagePath(name string) string {
|
||||
parts := strings.Split(name, ".")
|
||||
return parts[len(parts)-1]
|
||||
}
|
||||
|
||||
/////////////////// FailureView ////////////////////////
|
||||
|
||||
type FailureView struct {
|
||||
Message string
|
||||
Expected string
|
||||
Actual string
|
||||
}
|
||||
|
||||
////////////////////AssertionResult //////////////////////
|
||||
|
||||
type AssertionResult struct {
|
||||
File string
|
||||
Line int
|
||||
Expected string
|
||||
Actual string
|
||||
Failure string
|
||||
Error interface{}
|
||||
StackTrace string
|
||||
Skipped bool
|
||||
}
|
||||
|
||||
func NewFailureReport(failure string) *AssertionResult {
|
||||
report := new(AssertionResult)
|
||||
report.File, report.Line = caller()
|
||||
report.StackTrace = stackTrace()
|
||||
parseFailure(failure, report)
|
||||
return report
|
||||
}
|
||||
func parseFailure(failure string, report *AssertionResult) {
|
||||
view := new(FailureView)
|
||||
err := json.Unmarshal([]byte(failure), view)
|
||||
if err == nil {
|
||||
report.Failure = view.Message
|
||||
report.Expected = view.Expected
|
||||
report.Actual = view.Actual
|
||||
} else {
|
||||
report.Failure = failure
|
||||
}
|
||||
}
|
||||
func NewErrorReport(err interface{}) *AssertionResult {
|
||||
report := new(AssertionResult)
|
||||
report.File, report.Line = caller()
|
||||
report.StackTrace = fullStackTrace()
|
||||
report.Error = fmt.Sprintf("%v", err)
|
||||
return report
|
||||
}
|
||||
func NewSuccessReport() *AssertionResult {
|
||||
return new(AssertionResult)
|
||||
}
|
||||
func NewSkipReport() *AssertionResult {
|
||||
report := new(AssertionResult)
|
||||
report.File, report.Line = caller()
|
||||
report.StackTrace = fullStackTrace()
|
||||
report.Skipped = true
|
||||
return report
|
||||
}
|
||||
|
||||
func caller() (file string, line int) {
|
||||
file, line, _ = gotest.ResolveExternalCaller()
|
||||
return
|
||||
}
|
||||
|
||||
func stackTrace() string {
|
||||
buffer := make([]byte, 1024*64)
|
||||
n := runtime.Stack(buffer, false)
|
||||
return removeInternalEntries(string(buffer[:n]))
|
||||
}
|
||||
func fullStackTrace() string {
|
||||
buffer := make([]byte, 1024*64)
|
||||
n := runtime.Stack(buffer, true)
|
||||
return removeInternalEntries(string(buffer[:n]))
|
||||
}
|
||||
func removeInternalEntries(stack string) string {
|
||||
lines := strings.Split(stack, newline)
|
||||
filtered := []string{}
|
||||
for _, line := range lines {
|
||||
if !isExternal(line) {
|
||||
filtered = append(filtered, line)
|
||||
}
|
||||
}
|
||||
return strings.Join(filtered, newline)
|
||||
}
|
||||
func isExternal(line string) bool {
|
||||
for _, p := range internalPackages {
|
||||
if strings.Contains(line, p) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NOTE: any new packages that host goconvey packages will need to be added here!
|
||||
// An alternative is to scan the goconvey directory and then exclude stuff like
|
||||
// the examples package but that's nasty too.
|
||||
var internalPackages = []string{
|
||||
"goconvey/assertions",
|
||||
"goconvey/convey",
|
||||
"goconvey/execution",
|
||||
"goconvey/gotest",
|
||||
"goconvey/reporting",
|
||||
}
|
89
vendor/github.com/smartystreets/goconvey/convey/reporting/statistics.go
generated
vendored
Normal file
89
vendor/github.com/smartystreets/goconvey/convey/reporting/statistics.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
package reporting
|
||||
|
||||
import "fmt"
|
||||
|
||||
func (self *statistics) BeginStory(story *StoryReport) {}
|
||||
|
||||
func (self *statistics) Enter(scope *ScopeReport) {}
|
||||
|
||||
func (self *statistics) Report(report *AssertionResult) {
|
||||
if !self.failing && report.Failure != "" {
|
||||
self.failing = true
|
||||
}
|
||||
if !self.erroring && report.Error != nil {
|
||||
self.erroring = true
|
||||
}
|
||||
if report.Skipped {
|
||||
self.skipped += 1
|
||||
} else {
|
||||
self.total++
|
||||
}
|
||||
}
|
||||
|
||||
func (self *statistics) Exit() {}
|
||||
|
||||
func (self *statistics) EndStory() {
|
||||
if !self.suppressed {
|
||||
self.PrintSummary()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *statistics) Suppress() {
|
||||
self.suppressed = true
|
||||
}
|
||||
|
||||
func (self *statistics) PrintSummary() {
|
||||
self.reportAssertions()
|
||||
self.reportSkippedSections()
|
||||
self.completeReport()
|
||||
}
|
||||
func (self *statistics) reportAssertions() {
|
||||
self.decideColor()
|
||||
self.out.Print("\n%d total %s", self.total, plural("assertion", self.total))
|
||||
}
|
||||
func (self *statistics) decideColor() {
|
||||
if self.failing && !self.erroring {
|
||||
fmt.Print(yellowColor)
|
||||
} else if self.erroring {
|
||||
fmt.Print(redColor)
|
||||
} else {
|
||||
fmt.Print(greenColor)
|
||||
}
|
||||
}
|
||||
func (self *statistics) reportSkippedSections() {
|
||||
if self.skipped > 0 {
|
||||
fmt.Print(yellowColor)
|
||||
self.out.Print(" (one or more sections skipped)")
|
||||
}
|
||||
}
|
||||
func (self *statistics) completeReport() {
|
||||
fmt.Print(resetColor)
|
||||
self.out.Print("\n")
|
||||
self.out.Print("\n")
|
||||
}
|
||||
|
||||
func (self *statistics) Write(content []byte) (written int, err error) {
|
||||
return len(content), nil // no-op
|
||||
}
|
||||
|
||||
func NewStatisticsReporter(out *Printer) *statistics {
|
||||
self := statistics{}
|
||||
self.out = out
|
||||
return &self
|
||||
}
|
||||
|
||||
type statistics struct {
|
||||
out *Printer
|
||||
total int
|
||||
failing bool
|
||||
erroring bool
|
||||
skipped int
|
||||
suppressed bool
|
||||
}
|
||||
|
||||
func plural(word string, count int) string {
|
||||
if count == 1 {
|
||||
return word
|
||||
}
|
||||
return word + "s"
|
||||
}
|
73
vendor/github.com/smartystreets/goconvey/convey/reporting/story.go
generated
vendored
Normal file
73
vendor/github.com/smartystreets/goconvey/convey/reporting/story.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
// TODO: in order for this reporter to be completely honest
|
||||
// we need to retrofit to be more like the json reporter such that:
|
||||
// 1. it maintains ScopeResult collections, which count assertions
|
||||
// 2. it reports only after EndStory(), so that all tick marks
|
||||
// are placed near the appropriate title.
|
||||
// 3. Under unit test
|
||||
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type story struct {
|
||||
out *Printer
|
||||
titlesById map[string]string
|
||||
currentKey []string
|
||||
}
|
||||
|
||||
func (self *story) BeginStory(story *StoryReport) {}
|
||||
|
||||
func (self *story) Enter(scope *ScopeReport) {
|
||||
self.out.Indent()
|
||||
|
||||
self.currentKey = append(self.currentKey, scope.Title)
|
||||
ID := strings.Join(self.currentKey, "|")
|
||||
|
||||
if _, found := self.titlesById[ID]; !found {
|
||||
self.out.Println("")
|
||||
self.out.Print(scope.Title)
|
||||
self.out.Insert(" ")
|
||||
self.titlesById[ID] = scope.Title
|
||||
}
|
||||
}
|
||||
|
||||
func (self *story) Report(report *AssertionResult) {
|
||||
if report.Error != nil {
|
||||
fmt.Print(redColor)
|
||||
self.out.Insert(error_)
|
||||
} else if report.Failure != "" {
|
||||
fmt.Print(yellowColor)
|
||||
self.out.Insert(failure)
|
||||
} else if report.Skipped {
|
||||
fmt.Print(yellowColor)
|
||||
self.out.Insert(skip)
|
||||
} else {
|
||||
fmt.Print(greenColor)
|
||||
self.out.Insert(success)
|
||||
}
|
||||
fmt.Print(resetColor)
|
||||
}
|
||||
|
||||
func (self *story) Exit() {
|
||||
self.out.Dedent()
|
||||
self.currentKey = self.currentKey[:len(self.currentKey)-1]
|
||||
}
|
||||
|
||||
func (self *story) EndStory() {
|
||||
self.titlesById = make(map[string]string)
|
||||
self.out.Println("\n")
|
||||
}
|
||||
|
||||
func (self *story) Write(content []byte) (written int, err error) {
|
||||
return len(content), nil // no-op
|
||||
}
|
||||
|
||||
func NewStoryReporter(out *Printer) *story {
|
||||
self := new(story)
|
||||
self.out = out
|
||||
self.titlesById = make(map[string]string)
|
||||
return self
|
||||
}
|
Reference in New Issue
Block a user