1
0
mirror of https://github.com/beego/bee.git synced 2025-07-04 06:30:18 +00:00

add vendor

This commit is contained in:
astaxie
2016-12-05 23:07:45 +08:00
parent 71e23417c6
commit 28324a2756
141 changed files with 29958 additions and 0 deletions

View 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)
}

View 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

View 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
}

View 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 == ""
}

View 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()
}

View 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:
`

View 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)

View 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{}
}

View 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
}

View File

@ -0,0 +1,2 @@
#ignore
-timeout=1s

View 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",
}

View 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"
}

View 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
}