mirror of https://github.com/gogits/gogs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
8.5 KiB
218 lines
8.5 KiB
// 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() |
|
}
|
|
|