github.com/MontFerret/ferret@v0.18.0/pkg/compiler/compiler_logical_test.go (about)

     1  package compiler_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"testing"
     7  
     8  	. "github.com/smartystreets/goconvey/convey"
     9  
    10  	"github.com/MontFerret/ferret/pkg/compiler"
    11  	"github.com/MontFerret/ferret/pkg/runtime"
    12  	"github.com/MontFerret/ferret/pkg/runtime/core"
    13  )
    14  
    15  func TestLogicalOperators(t *testing.T) {
    16  	Convey("Should compile RETURN 2 > 1 AND 1 > 0", t, func() {
    17  		c := compiler.New()
    18  
    19  		p, err := c.Compile(`
    20  			RETURN 2 > 1 AND 1 > 0
    21  		`)
    22  
    23  		So(err, ShouldBeNil)
    24  		So(p, ShouldHaveSameTypeAs, &runtime.Program{})
    25  
    26  		out, err := p.Run(context.Background())
    27  
    28  		So(err, ShouldBeNil)
    29  		So(string(out), ShouldEqual, "true")
    30  	})
    31  
    32  	Convey("Should compile RETURN 2 > 1 OR 1 < 0", t, func() {
    33  		c := compiler.New()
    34  
    35  		p, err := c.Compile(`
    36  			RETURN 2 > 1 OR 1 < 0
    37  		`)
    38  
    39  		So(err, ShouldBeNil)
    40  		So(p, ShouldHaveSameTypeAs, &runtime.Program{})
    41  
    42  		out, err := p.Run(context.Background())
    43  
    44  		So(err, ShouldBeNil)
    45  		So(string(out), ShouldEqual, "true")
    46  	})
    47  
    48  	Convey("1 || 7  should return 1", t, func() {
    49  		c := compiler.New()
    50  
    51  		p, err := c.Compile(`
    52  			RETURN 1 || 7
    53  		`)
    54  
    55  		So(err, ShouldBeNil)
    56  
    57  		out, err := p.Run(context.Background())
    58  
    59  		So(err, ShouldBeNil)
    60  		So(string(out), ShouldEqual, "1")
    61  	})
    62  
    63  	Convey("NONE || 'foo'  should return 'foo'", t, func() {
    64  		c := compiler.New()
    65  
    66  		p, err := c.Compile(`
    67  			RETURN NONE || 'foo'
    68  		`)
    69  
    70  		So(err, ShouldBeNil)
    71  
    72  		out, err := p.Run(context.Background())
    73  
    74  		So(err, ShouldBeNil)
    75  		So(string(out), ShouldEqual, `"foo"`)
    76  	})
    77  
    78  	Convey("ERROR()? || 'boo'  should return 'boo'", t, func() {
    79  		c := compiler.New()
    80  		c.RegisterFunction("ERROR", func(ctx context.Context, args ...core.Value) (core.Value, error) {
    81  			return nil, errors.New("test")
    82  		})
    83  
    84  		p, err := c.Compile(`
    85  			RETURN ERROR()? || 'boo'
    86  		`)
    87  
    88  		So(err, ShouldBeNil)
    89  
    90  		out, err := p.Run(context.Background())
    91  
    92  		So(err, ShouldBeNil)
    93  		So(string(out), ShouldEqual, `"boo"`)
    94  	})
    95  
    96  	Convey("!ERROR()? && TRUE should return false", t, func() {
    97  		c := compiler.New()
    98  		c.RegisterFunction("ERROR", func(ctx context.Context, args ...core.Value) (core.Value, error) {
    99  			return nil, errors.New("test")
   100  		})
   101  
   102  		p, err := c.Compile(`
   103  			RETURN !ERROR()? && TRUE
   104  		`)
   105  
   106  		So(err, ShouldBeNil)
   107  
   108  		out, err := p.Run(context.Background())
   109  
   110  		So(err, ShouldBeNil)
   111  		So(string(out), ShouldEqual, `true`)
   112  	})
   113  
   114  	Convey("NONE && true should return null", t, func() {
   115  		c := compiler.New()
   116  
   117  		p, err := c.Compile(`
   118  			RETURN NONE && true
   119  		`)
   120  
   121  		So(err, ShouldBeNil)
   122  
   123  		out, err := p.Run(context.Background())
   124  
   125  		So(err, ShouldBeNil)
   126  		So(string(out), ShouldEqual, `null`)
   127  	})
   128  
   129  	Convey("'' && true  should return ''", t, func() {
   130  		c := compiler.New()
   131  
   132  		p, err := c.Compile(`
   133  			RETURN '' && true
   134  		`)
   135  
   136  		So(err, ShouldBeNil)
   137  
   138  		out, err := p.Run(context.Background())
   139  
   140  		So(err, ShouldBeNil)
   141  		So(string(out), ShouldEqual, `""`)
   142  	})
   143  
   144  	Convey("true && 23  should return '23", t, func() {
   145  		c := compiler.New()
   146  
   147  		p, err := c.Compile(`
   148  			RETURN true && 23 
   149  		`)
   150  
   151  		So(err, ShouldBeNil)
   152  
   153  		out, err := p.Run(context.Background())
   154  
   155  		So(err, ShouldBeNil)
   156  		So(string(out), ShouldEqual, `23`)
   157  	})
   158  
   159  	Convey("NOT TRUE should return false", t, func() {
   160  		c := compiler.New()
   161  
   162  		p, err := c.Compile(`
   163  			RETURN NOT TRUE
   164  		`)
   165  
   166  		So(err, ShouldBeNil)
   167  
   168  		out, err := p.Run(context.Background())
   169  
   170  		So(err, ShouldBeNil)
   171  		So(string(out), ShouldEqual, `false`)
   172  	})
   173  
   174  	Convey("NOT u.valid should return true", t, func() {
   175  		c := compiler.New()
   176  
   177  		p, err := c.Compile(`
   178  			LET u = { valid: false }
   179  
   180  			RETURN NOT u.valid
   181  		`)
   182  
   183  		So(err, ShouldBeNil)
   184  
   185  		out, err := p.Run(context.Background())
   186  
   187  		So(err, ShouldBeNil)
   188  		So(string(out), ShouldEqual, `true`)
   189  	})
   190  }
   191  
   192  func BenchmarkLogicalOperatorsAnd(b *testing.B) {
   193  	p := compiler.New().MustCompile(`
   194  			RETURN 2 > 1 AND 1 > 0
   195  		`)
   196  
   197  	for n := 0; n < b.N; n++ {
   198  		p.Run(context.Background())
   199  	}
   200  }
   201  
   202  func BenchmarkLogicalOperatorsOr(b *testing.B) {
   203  	p := compiler.New().MustCompile(`
   204  			RETURN 2 > 1 OR 1 < 0
   205  		`)
   206  
   207  	for n := 0; n < b.N; n++ {
   208  		p.Run(context.Background())
   209  	}
   210  }