aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go')
-rw-r--r--Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go669
1 files changed, 0 insertions, 669 deletions
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go
deleted file mode 100644
index a25ca8b9c..000000000
--- a/Godeps/_workspace/src/github.com/robertkrimen/otto/terst/terst.go
+++ /dev/null
@@ -1,669 +0,0 @@
-// This file was AUTOMATICALLY GENERATED by terst-import (smuggol) from github.com/robertkrimen/terst
-
-/*
-Package terst is a terse (terst = test + terse), easy-to-use testing library for Go.
-
-terst is compatible with (and works via) the standard testing package: http://golang.org/pkg/testing
-
- var is = terst.Is
-
- func Test(t *testing.T) {
- terst.Terst(t, func() {
- is("abc", "abc")
-
- is(1, ">", 0)
-
- var abc []int
- is(abc, nil)
- }
- }
-
-Do not import terst directly, instead use `terst-import` to copy it into your testing environment:
-
-https://github.com/robertkrimen/terst/tree/master/terst-import
-
- $ go get github.com/robertkrimen/terst/terst-import
-
- $ terst-import
-
-*/
-package terst
-
-import (
- "bytes"
- "errors"
- "fmt"
- "math/big"
- "reflect"
- "regexp"
- "runtime"
- "strings"
- "sync"
- "testing"
- "time"
-)
-
-// Is compares two values (got & expect) and returns true if the comparison is true,
-// false otherwise. In addition, if the comparison is false, Is will report the error
-// in a manner similar to testing.T.Error(...). Is also takes an optional argument,
-// a comparator, that changes how the comparison is made. The following
-// comparators are available:
-//
-// == # got == expect (default)
-// != # got != expect
-//
-// > # got > expect (float32, uint, uint16, int, int64, ...)
-// >= # got >= expect
-// < # got < expect
-// <= # got <= expect
-//
-// =~ # regexp.MustCompile(expect).Match{String}(got)
-// !~ # !regexp.MustCompile(expect).Match{String}(got)
-//
-// Basic usage with the default comparator (==):
-//
-// Is(<got>, <expect>)
-//
-// Specifying a different comparator:
-//
-// Is(<got>, <comparator>, <expect>)
-//
-// A simple comparison:
-//
-// Is(2 + 2, 4)
-//
-// A bit trickier:
-//
-// Is(1, ">", 0)
-// Is(2 + 2, "!=", 5)
-// Is("Nothing happens.", "=~", `ing(\s+)happens\.$`)
-//
-// Is should only be called under a Terst(t, ...) call. For a standalone version,
-// use IsErr. If no scope is found and the comparison is false, then Is will panic the error.
-//
-func Is(arguments ...interface{}) bool {
- err := IsErr(arguments...)
- if err != nil {
- call := Caller()
- if call == nil {
- panic(err)
- }
- call.Error(err)
- return false
- }
- return true
-}
-
-type (
- // ErrFail indicates a comparison failure (e.g. 0 > 1).
- ErrFail error
-
- // ErrInvalid indicates an invalid comparison (e.g. bool == string).
- ErrInvalid error
-)
-
-var errInvalid = errors.New("invalid")
-
-var registry = struct {
- table map[uintptr]*_scope
- lock sync.RWMutex
-}{
- table: map[uintptr]*_scope{},
-}
-
-func registerScope(pc uintptr, scope *_scope) {
- registry.lock.Lock()
- defer registry.lock.Unlock()
- registry.table[pc] = scope
-}
-
-func scope() *_scope {
- scope, _ := findScope()
- return scope
-}
-
-func floatCompare(a float64, b float64) int {
- if a > b {
- return 1
- } else if a < b {
- return -1
- }
- // NaN == NaN
- return 0
-}
-
-func bigIntCompare(a *big.Int, b *big.Int) int {
- return a.Cmp(b)
-}
-
-func bigInt(value int64) *big.Int {
- return big.NewInt(value)
-}
-
-func bigUint(value uint64) *big.Int {
- return big.NewInt(0).SetUint64(value)
-}
-
-type _toString interface {
- String() string
-}
-
-func toString(value interface{}) (string, error) {
- switch value := value.(type) {
- case string:
- return value, nil
- case _toString:
- return value.String(), nil
- case error:
- return value.Error(), nil
- }
- return "", errInvalid
-}
-
-func matchString(got string, expect *regexp.Regexp) (int, error) {
- if expect.MatchString(got) {
- return 0, nil
- }
- return -1, nil
-}
-
-func match(got []byte, expect *regexp.Regexp) (int, error) {
- if expect.Match(got) {
- return 0, nil
- }
- return -1, nil
-}
-
-func compareMatch(got, expect interface{}) (int, error) {
- switch got := got.(type) {
- case []byte:
- switch expect := expect.(type) {
- case string:
- matcher, err := regexp.Compile(expect)
- if err != nil {
- return 0, err
- }
- return match(got, matcher)
- case *regexp.Regexp:
- return match(got, expect)
- }
- default:
- if got, err := toString(got); err == nil {
- switch expect := expect.(type) {
- case string:
- matcher, err := regexp.Compile(expect)
- if err != nil {
- return 0, err
- }
- return matchString(got, matcher)
- case *regexp.Regexp:
- return matchString(got, expect)
- }
- } else {
- return 0, err
- }
- }
- return 0, errInvalid
-}
-
-func floatPromote(value reflect.Value) (float64, error) {
- kind := value.Kind()
- if reflect.Int <= kind && kind <= reflect.Int64 {
- return float64(value.Int()), nil
- }
- if reflect.Uint <= kind && kind <= reflect.Uint64 {
- return float64(value.Uint()), nil
- }
- if reflect.Float32 <= kind && kind <= reflect.Float64 {
- return value.Float(), nil
- }
- return 0, errInvalid
-}
-
-func bigIntPromote(value reflect.Value) (*big.Int, error) {
- kind := value.Kind()
- if reflect.Int <= kind && kind <= reflect.Int64 {
- return bigInt(value.Int()), nil
- }
- if reflect.Uint <= kind && kind <= reflect.Uint64 {
- return bigUint(value.Uint()), nil
- }
- return nil, errInvalid
-}
-
-func compareOther(got, expect interface{}) (int, error) {
- {
- switch expect.(type) {
- case float32, float64:
- return compareNumber(got, expect)
- case uint, uint8, uint16, uint32, uint64:
- return compareNumber(got, expect)
- case int, int8, int16, int32, int64:
- return compareNumber(got, expect)
- case string:
- var err error
- got, err = toString(got)
- if err != nil {
- return 0, err
- }
- case nil:
- got := reflect.ValueOf(got)
- switch got.Kind() {
- case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface:
- if got.IsNil() {
- return 0, nil
- }
- return -1, nil
- case reflect.Invalid: // reflect.Invalid: var abc interface{} = nil
- return 0, nil
- }
- return 0, errInvalid
- }
- }
-
- if reflect.ValueOf(got).Type() != reflect.ValueOf(expect).Type() {
- return 0, errInvalid
- }
-
- if reflect.DeepEqual(got, expect) {
- return 0, nil
- }
- return -1, nil
-}
-
-func compareNumber(got, expect interface{}) (int, error) {
- {
- got := reflect.ValueOf(got)
- k0 := got.Kind()
- expect := reflect.ValueOf(expect)
- k1 := expect.Kind()
- if reflect.Float32 <= k0 && k0 <= reflect.Float64 ||
- reflect.Float32 <= k1 && k1 <= reflect.Float64 {
- got, err := floatPromote(got)
- if err != nil {
- return 0, err
- }
- expect, err := floatPromote(expect)
- if err != nil {
- return 0, err
- }
- return floatCompare(got, expect), nil
- } else {
- got, err := bigIntPromote(got)
- if err != nil {
- return 0, err
- }
- expect, err := bigIntPromote(expect)
- if err != nil {
- return 0, err
- }
- return got.Cmp(expect), nil
- }
- }
-
- return 0, errInvalid
-}
-
-// IsErr compares two values (got & expect) and returns nil if the comparison is true, an ErrFail if
-// the comparison is false, or an ErrInvalid if the comparison is invalid. IsErr also
-// takes an optional argument, a comparator, that changes how the comparison is made.
-//
-// Is & IsErr are similar but different:
-//
-// Is(...) // Should only be called within a Terst(...) call
-// IsErr(...) // A standalone comparator, the same as Is, just without the automatic reporting
-//
-func IsErr(arguments ...interface{}) error {
- var got, expect interface{}
- comparator := "=="
- switch len(arguments) {
- case 0, 1:
- return fmt.Errorf("invalid number of arguments to IsErr: %d", len(arguments))
- case 2:
- got, expect = arguments[0], arguments[1]
- default:
- if value, ok := arguments[1].(string); ok {
- comparator = value
- } else {
- return fmt.Errorf("invalid comparator: %v", arguments[1])
- }
- got, expect = arguments[0], arguments[2]
- }
-
- var result int
- var err error
-
- switch comparator {
- case "<", "<=", ">", ">=":
- result, err = compareNumber(got, expect)
- case "=~", "!~":
- result, err = compareMatch(got, expect)
- case "==", "!=":
- result, err = compareOther(got, expect)
- default:
- return fmt.Errorf("invalid comparator: %s", comparator)
- }
-
- if err == errInvalid {
- return ErrInvalid(fmt.Errorf(
- "\nINVALID (%s):\n got: %v (%T)\n expected: %v (%T)",
- comparator,
- got, got,
- expect, expect,
- ))
- } else if err != nil {
- return err
- }
-
- equality, pass := false, false
-
- switch comparator {
- case "==", "=~":
- equality = true
- pass = result == 0
- case "!=", "!~":
- equality = true
- pass = result != 0
- case "<":
- pass = result < 0
- case "<=":
- pass = result <= 0
- case ">":
- pass = result > 0
- case ">=":
- pass = result >= 0
- }
-
- if !pass {
- if equality {
- if comparator[1] == '~' {
- if value, ok := got.([]byte); ok {
- return ErrFail(fmt.Errorf(
- "\nFAIL (%s)\n got: %s %v%s\nexpected: %v%s",
- comparator,
- value, got, typeKindString(got),
- expect, typeKindString(expect),
- ))
- }
- }
- return ErrFail(fmt.Errorf(
- "\nFAIL (%s)\n got: %v%s\nexpected: %v%s",
- comparator,
- got, typeKindString(got),
- expect, typeKindString(expect),
- ))
- }
- return ErrFail(fmt.Errorf(
- "\nFAIL (%s)\n got: %v%s\nexpected: %s %v%s",
- comparator,
- got, typeKindString(got),
- comparator, expect, typeKindString(expect),
- ))
- }
-
- return nil
-}
-
-func typeKindString(value interface{}) string {
- reflectValue := reflect.ValueOf(value)
- kind := reflectValue.Kind().String()
- result := fmt.Sprintf("%T", value)
- if kind == result {
- if kind == "string" {
- return ""
- }
- return fmt.Sprintf(" (%T)", value)
- }
- return fmt.Sprintf(" (%T=%s)", value, kind)
-}
-
-func (scope *_scope) reset() {
- scope.name = ""
- scope.output = scope.output[:]
- scope.start = time.Time{}
- scope.duration = 0
-}
-
-// Terst creates a testing scope, where Is can be called and errors will be reported
-// according to the top-level location of the comparison, and not where the Is call
-// actually takes place. For example:
-//
-// func test(value int) {
-// Is(value, 5) // <--- This failure is reported below.
-// }
-//
-// Terst(t, func(){
-//
-// Is(2, ">", 3) // <--- An error is reported here.
-//
-// test(5) // <--- An error is reported here.
-//
-// })
-//
-func Terst(t *testing.T, arguments ...func()) {
- scope := &_scope{
- t: t,
- }
-
- pc, _, _, ok := runtime.Caller(1) // TODO Associate with the Test... func
- if !ok {
- panic("Here be dragons.")
- }
-
- _, scope.testFunc = findTestFunc()
-
- registerScope(pc, scope)
-
- for _, fn := range arguments {
- func() {
- scope.reset()
- name := scope.testFunc.Name()
- index := strings.LastIndex(scope.testFunc.Name(), ".")
- if index >= 0 {
- name = name[index+1:] + "(Terst)"
- } else {
- name = "(Terst)"
- }
- name = "(Terst)"
- scope.name = name
- scope.start = time.Now()
- defer func() {
- scope.duration = time.Now().Sub(scope.start)
- if err := recover(); err != nil {
- scope.t.Fail()
- scope.report()
- panic(err)
- }
- scope.report()
- }()
- fn()
- }()
- }
-}
-
-// From "testing"
-func (scope *_scope) report() {
- format := "~~~ %s: (Terst)\n%s"
- if scope.t.Failed() {
- fmt.Printf(format, "FAIL", scope.output)
- } else if testing.Verbose() && len(scope.output) > 0 {
- fmt.Printf(format, "PASS", scope.output)
- }
-}
-
-func (scope *_scope) log(call _entry, str string) {
- scope.mu.Lock()
- defer scope.mu.Unlock()
- scope.output = append(scope.output, decorate(call, str)...)
-}
-
-// decorate prefixes the string with the file and line of the call site
-// and inserts the final newline if needed and indentation tabs for formascing.
-func decorate(call _entry, s string) string {
-
- file, line := call.File, call.Line
- if call.PC > 0 {
- // Truncate file name at last file name separator.
- if index := strings.LastIndex(file, "/"); index >= 0 {
- file = file[index+1:]
- } else if index = strings.LastIndex(file, "\\"); index >= 0 {
- file = file[index+1:]
- }
- } else {
- file = "???"
- line = 1
- }
- buf := new(bytes.Buffer)
- // Every line is indented at least one tab.
- buf.WriteByte('\t')
- fmt.Fprintf(buf, "%s:%d: ", file, line)
- lines := strings.Split(s, "\n")
- if l := len(lines); l > 1 && lines[l-1] == "" {
- lines = lines[:l-1]
- }
- for i, line := range lines {
- if i > 0 {
- // Second and subsequent lines are indented an extra tab.
- buf.WriteString("\n\t\t")
- }
- buf.WriteString(line)
- }
- buf.WriteByte('\n')
- return buf.String()
-}
-
-func findScope() (*_scope, _entry) {
- registry.lock.RLock()
- defer registry.lock.RUnlock()
- table := registry.table
- depth := 2 // Starting depth
- call := _entry{}
- for {
- pc, _, _, ok := runtime.Caller(depth)
- if !ok {
- break
- }
- if scope, exists := table[pc]; exists {
- pc, file, line, _ := runtime.Caller(depth - 3) // Terst(...) + func(){}() + fn() => ???()
- call.PC = pc
- call.File = file
- call.Line = line
- return scope, call
- }
- depth++
- }
- return nil, _entry{}
-}
-
-// Call is a reference to a line immediately under a Terst testing scope.
-type Call struct {
- scope *_scope
- entry _entry
-}
-
-// Caller will search the stack, looking for a Terst testing scope. If a scope
-// is found, then Caller returns a Call for logging errors, accessing testing.T, etc.
-// If no scope is found, Caller returns nil.
-func Caller() *Call {
- scope, entry := findScope()
- if scope == nil {
- return nil
- }
- return &Call{
- scope: scope,
- entry: entry,
- }
-}
-
-// TestFunc returns the *runtime.Func entry for the top-level Test...(t testing.T)
-// function.
-func (cl *Call) TestFunc() *runtime.Func {
- return cl.scope.testFunc
-}
-
-// T returns the original testing.T passed to Terst(...)
-func (cl *Call) T() *testing.T {
- return cl.scope.t
-}
-
-// Log is the terst version of `testing.T.Log`
-func (cl *Call) Log(arguments ...interface{}) {
- cl.scope.log(cl.entry, fmt.Sprintln(arguments...))
-}
-
-// Logf is the terst version of `testing.T.Logf`
-func (cl *Call) Logf(format string, arguments ...interface{}) {
- cl.scope.log(cl.entry, fmt.Sprintf(format, arguments...))
-}
-
-// Error is the terst version of `testing.T.Error`
-func (cl *Call) Error(arguments ...interface{}) {
- cl.scope.log(cl.entry, fmt.Sprintln(arguments...))
- cl.scope.t.Fail()
-}
-
-// Errorf is the terst version of `testing.T.Errorf`
-func (cl *Call) Errorf(format string, arguments ...interface{}) {
- cl.scope.log(cl.entry, fmt.Sprintf(format, arguments...))
- cl.scope.t.Fail()
-}
-
-// Skip is the terst version of `testing.T.Skip`
-func (cl *Call) Skip(arguments ...interface{}) {
- cl.scope.log(cl.entry, fmt.Sprintln(arguments...))
- cl.scope.t.SkipNow()
-}
-
-// Skipf is the terst version of `testing.T.Skipf`
-func (cl *Call) Skipf(format string, arguments ...interface{}) {
- cl.scope.log(cl.entry, fmt.Sprintf(format, arguments...))
- cl.scope.t.SkipNow()
-}
-
-type _scope struct {
- t *testing.T
- testFunc *runtime.Func
- name string
- mu sync.RWMutex
- output []byte
- start time.Time
- duration time.Duration
-}
-
-type _entry struct {
- PC uintptr
- File string
- Line int
- Func *runtime.Func
-}
-
-func _findFunc(match string) (_entry, *runtime.Func) {
- depth := 2 // Starting depth
- for {
- pc, file, line, ok := runtime.Caller(depth)
- if !ok {
- break
- }
- fn := runtime.FuncForPC(pc)
- name := fn.Name()
- if index := strings.LastIndex(name, match); index >= 0 {
- // Assume we have an instance of TestXyzzy in a _test file
- return _entry{
- PC: pc,
- File: file,
- Line: line,
- Func: fn,
- }, fn
- }
- depth++
- }
- return _entry{}, nil
-}
-
-func findTestFunc() (_entry, *runtime.Func) {
- return _findFunc(".Test")
-}
-
-func findTerstFunc() (_entry, *runtime.Func) {
- return _findFunc(".Terst")
-}