mirror of
https://github.com/MontFerret/ferret.git
synced 2025-03-19 21:28:32 +02:00
86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
|
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())
|
||
|
}
|