EvalBool and Interpolation fixes (#424)
* A new attempt at Interpolation and EvalBool * One small merge fix * Remove some fmt.Printfs
This commit is contained in:
@@ -16,11 +16,12 @@ import (
|
||||
"gopkg.in/godo.v2/glob"
|
||||
)
|
||||
|
||||
var contextPattern, expressionPattern *regexp.Regexp
|
||||
var contextPattern, expressionPattern, operatorPattern *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
contextPattern = regexp.MustCompile(`^(\w+(?:\[.+])*)(?:\.([\w-]+))?(.*)$`)
|
||||
contextPattern = regexp.MustCompile(`^([^.]*(?:\[.+])*)(?:\.([\w-]+))?(.*)$`)
|
||||
expressionPattern = regexp.MustCompile(`\${{\s*(.+?)\s*}}`)
|
||||
operatorPattern = regexp.MustCompile("^[!=><|&]+$")
|
||||
}
|
||||
|
||||
// NewExpressionEvaluator creates a new evaluator
|
||||
@@ -49,8 +50,9 @@ func (sc *StepContext) NewExpressionEvaluator() ExpressionEvaluator {
|
||||
|
||||
// ExpressionEvaluator is the interface for evaluating expressions
|
||||
type ExpressionEvaluator interface {
|
||||
Evaluate(string) (string, error)
|
||||
Evaluate(string) (string, bool, error)
|
||||
Interpolate(string) string
|
||||
InterpolateWithStringCheck(string) (string, bool)
|
||||
Rewrite(string) string
|
||||
}
|
||||
|
||||
@@ -58,7 +60,7 @@ type expressionEvaluator struct {
|
||||
vm *otto.Otto
|
||||
}
|
||||
|
||||
func (ee *expressionEvaluator) Evaluate(in string) (string, error) {
|
||||
func (ee *expressionEvaluator) Evaluate(in string) (string, bool, error) {
|
||||
re := ee.Rewrite(in)
|
||||
if re != in {
|
||||
log.Debugf("Evaluating '%s' instead of '%s'", re, in)
|
||||
@@ -66,32 +68,40 @@ func (ee *expressionEvaluator) Evaluate(in string) (string, error) {
|
||||
|
||||
val, err := ee.vm.Run(re)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", false, err
|
||||
}
|
||||
if val.IsNull() || val.IsUndefined() {
|
||||
return "", nil
|
||||
return "", false, nil
|
||||
}
|
||||
return val.ToString()
|
||||
valAsString, err := val.ToString()
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
|
||||
return valAsString, val.IsString(), err
|
||||
}
|
||||
|
||||
func (ee *expressionEvaluator) Interpolate(in string) string {
|
||||
func (ee *expressionEvaluator) Interpolate(in string) string{
|
||||
interpolated, _ := ee.InterpolateWithStringCheck(in)
|
||||
return interpolated
|
||||
}
|
||||
|
||||
func (ee *expressionEvaluator) InterpolateWithStringCheck(in string) (string, bool) {
|
||||
errList := make([]error, 0)
|
||||
|
||||
out := in
|
||||
isString := false
|
||||
for {
|
||||
out = expressionPattern.ReplaceAllStringFunc(in, func(match string) string {
|
||||
// Extract and trim the actual expression inside ${{...}} delimiters
|
||||
expression := expressionPattern.ReplaceAllString(match, "$1")
|
||||
|
||||
// Evaluate the expression and retrieve errors if any
|
||||
negatedExpression := strings.HasPrefix(expression, "!")
|
||||
evaluated, err := ee.Evaluate(strings.ReplaceAll(expression, "!", ""))
|
||||
evaluated, evaluatedIsString, err := ee.Evaluate(expression)
|
||||
if err != nil {
|
||||
errList = append(errList, err)
|
||||
}
|
||||
if negatedExpression {
|
||||
evaluated = fmt.Sprintf("!%s", evaluated)
|
||||
}
|
||||
isString = evaluatedIsString
|
||||
return evaluated
|
||||
})
|
||||
if len(errList) > 0 {
|
||||
@@ -104,7 +114,7 @@ func (ee *expressionEvaluator) Interpolate(in string) string {
|
||||
}
|
||||
in = out
|
||||
}
|
||||
return out
|
||||
return out, isString
|
||||
}
|
||||
|
||||
// Rewrite tries to transform any javascript property accessor into its bracket notation.
|
||||
|
Reference in New Issue
Block a user