1
0
mirror of https://github.com/MontFerret/ferret.git synced 2025-03-19 21:28:32 +02:00
ferret/pkg/stdlib/testing/base/assertion.go

86 lines
1.9 KiB
Go
Raw Normal View History

package base
import (
"context"
"fmt"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
)
type AssertionFn func(ctx context.Context, args []core.Value) (bool, error)
type MessageFn func(args []core.Value) string
type Assertion struct {
DefaultMessage MessageFn
MinArgs int
MaxArgs int
Fn AssertionFn
}
func NewPositiveAssertion(assertion Assertion) core.Function {
return newInternal(assertion, true)
}
func NewNegativeAssertion(assertion Assertion) core.Function {
return newInternal(assertion, false)
}
func newInternal(assertion Assertion, connotation bool) core.Function {
return func(ctx context.Context, args ...core.Value) (core.Value, error) {
err := core.ValidateArgs(args, assertion.MinArgs, assertion.MaxArgs)
if err != nil {
return values.None, err
}
res, err := assertion.Fn(ctx, args)
if err != nil {
return values.None, err
}
if res == connotation {
return values.None, nil
}
return values.None, toError(assertion, args, connotation)
}
}
func toError(assertion Assertion, args []core.Value, positive bool) error {
if len(args) != assertion.MaxArgs {
connotation := ""
if !positive {
connotation = "not "
}
if assertion.MaxArgs > 1 {
actual := args[0]
var msg string
if assertion.DefaultMessage != nil {
msg = assertion.DefaultMessage(args)
} else {
if len(args) > 1 {
msg = fmt.Sprintf("be %s", args[1].String())
} else {
msg = "exist"
}
}
return core.Error(ErrAssertion, fmt.Sprintf("expected %s %sto %s", FormatValue(actual), connotation, msg))
}
return core.Error(ErrAssertion, fmt.Sprintf("expected to %s%s", connotation, assertion.DefaultMessage(args)))
}
// Last argument is always is a custom message
msg := args[assertion.MaxArgs-1]
return core.Error(ErrAssertion, msg.String())
}