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 }