...

Source file src/github.com/noirbizarre/gonja/exec/tests.go

Documentation: github.com/noirbizarre/gonja/exec

     1  package exec
     2  
     3  import (
     4  	"github.com/pkg/errors"
     5  
     6  	"github.com/noirbizarre/gonja/nodes"
     7  )
     8  
     9  // TestFunction is the type test functions must fulfil
    10  type TestFunction func(*Context, *Value, *VarArgs) (bool, error)
    11  
    12  // TestSet maps test names to their TestFunction handler
    13  type TestSet map[string]TestFunction
    14  
    15  // Exists returns true if the given test is already registered
    16  func (ts TestSet) Exists(name string) bool {
    17  	_, existing := ts[name]
    18  	return existing
    19  }
    20  
    21  // Register registers a new test. If there's already a test with the same
    22  // name, RegisterTest will panic. You usually want to call this
    23  // function in the test's init() function:
    24  // http://golang.org/doc/effective_go.html#init
    25  //
    26  // See http://www.florian-schlachter.de/post/gonja/ for more about
    27  // writing tests and tags.
    28  func (ts *TestSet) Register(name string, fn TestFunction) error {
    29  	if ts.Exists(name) {
    30  		return errors.Errorf("test with name '%s' is already registered", name)
    31  	}
    32  	(*ts)[name] = fn
    33  	return nil
    34  }
    35  
    36  // Replace replaces an already registered test with a new implementation. Use this
    37  // function with caution since it allows you to change existing test behaviour.
    38  func (ts *TestSet) Replace(name string, fn TestFunction) error {
    39  	if !ts.Exists(name) {
    40  		return errors.Errorf("test with name '%s' does not exist (therefore cannot be overridden)", name)
    41  	}
    42  	(*ts)[name] = fn
    43  	return nil
    44  }
    45  
    46  func (ts *TestSet) Update(other TestSet) TestSet {
    47  	for name, test := range other {
    48  		(*ts)[name] = test
    49  	}
    50  	return *ts
    51  }
    52  
    53  func (e *Evaluator) EvalTest(expr *nodes.TestExpression) *Value {
    54  	value := e.Eval(expr.Expression)
    55  	// if value.IsError() {
    56  	// 	return AsValue(errors.Wrapf(value, `Unable to evaluate expresion %s`, expr.Expression))
    57  	// }
    58  
    59  	return e.ExecuteTest(expr.Test, value)
    60  }
    61  
    62  func (e *Evaluator) ExecuteTest(tc *nodes.TestCall, v *Value) *Value {
    63  	params := &VarArgs{
    64  		Args:   []*Value{},
    65  		KwArgs: map[string]*Value{},
    66  	}
    67  
    68  	for _, param := range tc.Args {
    69  		value := e.Eval(param)
    70  		if value.IsError() {
    71  			return AsValue(errors.Wrapf(value, `Unable to evaluate parameter %s`, param))
    72  		}
    73  		params.Args = append(params.Args, value)
    74  	}
    75  
    76  	for key, param := range tc.Kwargs {
    77  		value := e.Eval(param)
    78  		if value.IsError() {
    79  			return AsValue(errors.Wrapf(value, `Unable to evaluate parameter %s`, param))
    80  		}
    81  		params.KwArgs[key] = value
    82  	}
    83  
    84  	return e.ExecuteTestByName(tc.Name, v, params)
    85  }
    86  
    87  func (e *Evaluator) ExecuteTestByName(name string, in *Value, params *VarArgs) *Value {
    88  	if !e.Tests.Exists(name) {
    89  		return AsValue(errors.Errorf(`Test "%s" not found`, name))
    90  	}
    91  	test, _ := (*e.Tests)[name]
    92  
    93  	result, err := test(e.Ctx, in, params)
    94  	if err != nil {
    95  		return AsValue(errors.Wrapf(err, `Unable to execute test %s`, name))
    96  	} else {
    97  		return AsValue(result)
    98  	}
    99  }
   100  

View as plain text