github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/block_test.go (about)

     1  package expressions_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/MontFerret/ferret/pkg/runtime/collections"
     8  
     9  	. "github.com/smartystreets/goconvey/convey"
    10  
    11  	"github.com/MontFerret/ferret/pkg/runtime/core"
    12  	"github.com/MontFerret/ferret/pkg/runtime/expressions"
    13  	"github.com/MontFerret/ferret/pkg/runtime/values"
    14  )
    15  
    16  type IterableFn func(ctx context.Context, scope *core.Scope) (collections.Iterator, error)
    17  
    18  func (f IterableFn) Iterate(ctx context.Context, scope *core.Scope) (collections.Iterator, error) {
    19  	return f(ctx, scope)
    20  }
    21  
    22  type ExpressionFn func(ctx context.Context, scope *core.Scope) (core.Value, error)
    23  
    24  func (f ExpressionFn) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) {
    25  	return f(ctx, scope)
    26  }
    27  
    28  func TestBlock(t *testing.T) {
    29  	newExp := func(values []core.Value) (*expressions.BlockExpression, error) {
    30  		iter, err := collections.NewDefaultSliceIterator(values)
    31  
    32  		if err != nil {
    33  			return nil, err
    34  		}
    35  
    36  		return expressions.NewBlockExpression(IterableFn(func(ctx context.Context, scope *core.Scope) (collections.Iterator, error) {
    37  			return iter, nil
    38  		}))
    39  	}
    40  
    41  	Convey("Should create a block expression", t, func() {
    42  		s, err := newExp(make([]core.Value, 0, 10))
    43  
    44  		So(err, ShouldBeNil)
    45  		So(s, ShouldHaveSameTypeAs, &expressions.BlockExpression{})
    46  	})
    47  
    48  	Convey("Should add a new expression of a default type", t, func() {
    49  		s, _ := newExp(make([]core.Value, 0, 10))
    50  
    51  		sourceMap := core.NewSourceMap("test", 1, 1)
    52  		exp, err := expressions.NewVariableExpression(sourceMap, "testExp")
    53  		So(err, ShouldBeNil)
    54  
    55  		s.Add(exp)
    56  	})
    57  
    58  	Convey("Should exec a block expression", t, func() {
    59  		s, _ := newExp(make([]core.Value, 0, 10))
    60  
    61  		sourceMap := core.NewSourceMap("test", 1, 1)
    62  		exp, err := expressions.NewVariableDeclarationExpression(sourceMap, "test", ExpressionFn(func(ctx context.Context, scope *core.Scope) (core.Value, error) {
    63  			return values.NewString("value"), nil
    64  		}))
    65  		So(err, ShouldBeNil)
    66  
    67  		s.Add(exp)
    68  
    69  		rootScope, _ := core.NewRootScope()
    70  		scope := rootScope.Fork()
    71  
    72  		_, err = s.Exec(context.Background(), scope)
    73  		So(err, ShouldBeNil)
    74  
    75  		val, err := scope.GetVariable("test")
    76  		So(err, ShouldBeNil)
    77  
    78  		So(val, ShouldEqual, "value")
    79  	})
    80  
    81  	Convey("Should not exec a nil block expression", t, func() {
    82  		s, _ := newExp(make([]core.Value, 0, 10))
    83  
    84  		sourceMap := core.NewSourceMap("test", 1, 1)
    85  		exp, err := expressions.NewVariableExpression(sourceMap, "test")
    86  		So(err, ShouldBeNil)
    87  
    88  		s.Add(exp)
    89  		So(err, ShouldBeNil)
    90  
    91  		rootScope, fn := core.NewRootScope()
    92  		scope := rootScope.Fork()
    93  		scope.SetVariable("test", values.NewString("value"))
    94  		fn()
    95  
    96  		value, err := s.Exec(context.Background(), scope)
    97  		So(err, ShouldBeNil)
    98  		So(value, ShouldHaveSameTypeAs, values.None)
    99  	})
   100  
   101  	Convey("Should return an iterator", t, func() {
   102  		s, _ := newExp([]core.Value{
   103  			values.NewInt(1),
   104  			values.NewInt(2),
   105  			values.NewInt(3),
   106  		})
   107  		sourceMap := core.NewSourceMap("test", 1, 1)
   108  		exp, _ := expressions.NewVariableExpression(sourceMap, "test")
   109  		s.Add(exp)
   110  
   111  		rootScope, _ := core.NewRootScope()
   112  		scope := rootScope.Fork()
   113  		scope.SetVariable("test", values.NewString("value"))
   114  
   115  		iter, err := s.Iterate(context.Background(), scope)
   116  		So(err, ShouldBeNil)
   117  
   118  		items, err := collections.ToSlice(context.Background(), scope, iter)
   119  		So(err, ShouldBeNil)
   120  		So(items, ShouldHaveLength, 3)
   121  	})
   122  
   123  	Convey("Should stop an execution when context is cancelled", t, func() {
   124  		s, _ := newExp(make([]core.Value, 0, 10))
   125  		sourceMap := core.NewSourceMap("test", 1, 1)
   126  		exp, _ := expressions.NewVariableExpression(sourceMap, "test")
   127  		s.Add(exp)
   128  
   129  		rootScope, _ := core.NewRootScope()
   130  		scope := rootScope.Fork()
   131  		scope.SetVariable("test", values.NewString("value"))
   132  
   133  		ctx, cancel := context.WithCancel(context.Background())
   134  		cancel()
   135  
   136  		_, err := s.Exec(ctx, scope)
   137  		So(err, ShouldEqual, core.ErrTerminated)
   138  	})
   139  
   140  	Convey("Should stop an execution when context is cancelled 2", t, func() {
   141  		s, _ := newExp([]core.Value{
   142  			values.NewInt(1),
   143  			values.NewInt(2),
   144  			values.NewInt(3),
   145  		})
   146  		sourceMap := core.NewSourceMap("test", 1, 1)
   147  		exp, _ := expressions.NewVariableExpression(sourceMap, "test")
   148  		s.Add(exp)
   149  
   150  		rootScope, _ := core.NewRootScope()
   151  		scope := rootScope.Fork()
   152  		scope.SetVariable("test", values.NewString("value"))
   153  
   154  		ctx, cancel := context.WithCancel(context.Background())
   155  		cancel()
   156  
   157  		_, err := s.Iterate(ctx, scope)
   158  		So(err, ShouldEqual, core.ErrTerminated)
   159  	})
   160  }