71 lines
1.4 KiB
Go
71 lines
1.4 KiB
Go
package assert
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
|
|
eval "github.com/novalagung/go-eek"
|
|
|
|
"gitlab.com/CRThaze/cworthy/exits"
|
|
)
|
|
|
|
type EvalVar eval.Var
|
|
type EvalVal eval.ExecVar
|
|
|
|
const (
|
|
stdAssertFailureFmt = "%s%s%s:%d %s%sAssertion `%s` failed.\n"
|
|
)
|
|
|
|
var (
|
|
AssertFailureFmt = stdAssertFailureFmt
|
|
AssertionStream = os.Stderr
|
|
)
|
|
|
|
func assertFailBase(frmt, assertion, file string, line int, function string) {
|
|
fmt.Fprintf(AssertionStream, frmt, file, line, function, assertion)
|
|
exits.Abort()
|
|
}
|
|
|
|
func assertFail(frmt, expr string) {
|
|
if pc, file, line, ok := runtime.Caller(2); ok {
|
|
frames := runtime.CallersFrames([]uintptr{pc})
|
|
firstFrame, _ := frames.Next()
|
|
assertFailBase(frmt, expr, file, line, firstFrame.Function)
|
|
}
|
|
}
|
|
|
|
func Assert(exprResult bool) {
|
|
if exprResult {
|
|
return
|
|
}
|
|
assertFail(AssertFailureFmt, "")
|
|
}
|
|
|
|
func AssertEval(expr string, vals EvalVal, vars ...EvalVar) {
|
|
defer func() {
|
|
if paniced := recover(); paniced != nil {
|
|
assertFail("Assertion paniced", expr)
|
|
}
|
|
}()
|
|
|
|
obj := eval.New("Assertion Eval", expr)
|
|
for _, v := range vars {
|
|
obj.DefineVariable(v)
|
|
}
|
|
obj.PrepareEvaluation(expr)
|
|
if err := obj.Build(); err != nil {
|
|
assertFail("Assertion cannot build", expr)
|
|
}
|
|
resultItf, err := obj.Evaluate(vals)
|
|
if err != nil {
|
|
assertFail("Assertion could not be evaluated", expr)
|
|
}
|
|
if result, ok := resultItf.(bool); !ok {
|
|
panic("Invalid assertion")
|
|
} else if result {
|
|
return
|
|
}
|
|
assertFail(AssertFailureFmt, expr)
|
|
}
|