kaniko/vendor/github.com/otiai10/mint/testee.go

146 lines
3.7 KiB
Go

package mint
import (
"fmt"
"path/filepath"
"reflect"
"regexp"
"runtime"
"testing"
"github.com/otiai10/mint/mquery"
)
// Testee is holder of interfaces which user want to assert
// and also has its result.
type Testee struct {
t *testing.T
actual interface{}
expected interface{}
dry bool
not bool
deeply bool
result MintResult
required bool
verbose bool
// origin string // Only used when querying
}
// Query queries the actual value with given query string.
func (testee *Testee) Query(query string) *Testee {
// testee.origin = fmt.Sprintf("%T", testee.actual)
testee.actual = mquery.Query(testee.actual, query)
return testee
}
// ToBe can assert the testee to equal the parameter of this func.
// OS will exit with code 1, when the assertion fail.
// If you don't want to exit, see "Dry()".
func (testee *Testee) ToBe(expected interface{}) MintResult {
if judge(testee.actual, expected, testee.not, testee.deeply) {
return testee.result
}
testee.expected = expected
return testee.failed(failToBe)
}
// Match can assert the testee to match with specified regular expression.
// It uses `regexp.MustCompile`, it's due to caller to make sure it's valid regexp.
// OS will exit with code 1, when the assertion fail.
// If you don't want to exit, see "Dry()".
func (testee *Testee) Match(expression string) MintResult {
exp := regexp.MustCompile(expression)
matched := exp.MatchString(fmt.Sprintf("%v", testee.actual))
if judge(matched, true, testee.not, testee.deeply) {
return testee.result
}
testee.expected = expression
return testee.failed(failToMatch)
}
// In can assert the testee is in given array.
func (testee *Testee) In(expecteds ...interface{}) MintResult {
for _, expected := range expecteds {
if judge(testee.actual, expected, testee.not, testee.deeply) {
return testee.result
}
}
testee.expected = expecteds
return testee.failed(failIn)
}
// TypeOf can assert the type of testee to equal the parameter of this func.
// OS will exit with code 1, when the assertion fail.
// If you don't want to exit, see "Dry()".
func (testee *Testee) TypeOf(typeName string) MintResult {
if judge(reflect.TypeOf(testee.actual).String(), typeName, testee.not, testee.deeply) {
return testee.result
}
testee.expected = typeName
return testee.failed(failType)
}
// Not makes following assertion conversed.
func (testee *Testee) Not() *Testee {
testee.not = true
return testee
}
// Dry makes the testee NOT to call "Fail()".
// Use this if you want to fail test in a purpose.
func (testee *Testee) Dry() *Testee {
testee.dry = true
return testee
}
// Deeply makes following assertions use `reflect.DeepEqual`.
// You had better use this to compare reference type objects.
func (testee *Testee) Deeply() *Testee {
testee.deeply = true
return testee
}
func (testee *Testee) failed(failure int) MintResult {
message := testee.toText(failure)
testee.result.ok = false
testee.result.message = message
if !testee.dry {
fmt.Println(colorize["red"](message))
if testee.required {
testee.t.FailNow()
} else {
testee.t.Fail()
}
}
return testee.result
}
func (testee *Testee) toText(fail int) string {
not := ""
if testee.not {
not = "NOT "
}
_, file, line, _ := runtime.Caller(3)
// if testee.origin != "" {
// testee.origin = fmt.Sprintf("(queried from %s)", testee.origin)
// }
return fmt.Sprintf(
scolds[fail],
filepath.Base(file), line,
not,
testee.expected,
testee.actual,
)
}
// Log only output if -v flag is given.
// This is because the standard "t.Testing.Log" method decorates
// its caller: runtime.Caller(3) automatically.
func (testee *Testee) Log(args ...interface{}) {
if !testee.verbose {
return
}
fmt.Print(args...)
}