github.com/MontFerret/ferret@v0.18.0/pkg/compiler/compiler_for_while_test.go (about) 1 package compiler_test 2 3 import ( 4 "context" 5 "testing" 6 7 . "github.com/smartystreets/goconvey/convey" 8 9 "github.com/MontFerret/ferret/pkg/compiler" 10 "github.com/MontFerret/ferret/pkg/runtime" 11 "github.com/MontFerret/ferret/pkg/runtime/core" 12 "github.com/MontFerret/ferret/pkg/runtime/values" 13 ) 14 15 func TestForWhile(t *testing.T) { 16 Convey("FOR WHILE", t, func() { 17 Convey("WHILE", func() { 18 Convey("Should compile FOR i WHILE false RETURN i", func() { 19 c := compiler.New() 20 21 p, err := c.Compile(` 22 FOR i WHILE false 23 RETURN i 24 `) 25 26 So(err, ShouldBeNil) 27 So(p, ShouldHaveSameTypeAs, &runtime.Program{}) 28 29 out, err := p.Run(context.Background()) 30 31 So(err, ShouldBeNil) 32 So(string(out), ShouldEqual, "[]") 33 }) 34 35 Convey("Should compile FOR i WHILE [] RETURN i", func() { 36 c := compiler.New() 37 38 p, err := c.Compile(` 39 FOR i WHILE [] 40 RETURN i 41 `) 42 43 So(err, ShouldBeNil) 44 So(p, ShouldHaveSameTypeAs, &runtime.Program{}) 45 46 out, err := p.Run(context.Background()) 47 48 So(err, ShouldBeNil) 49 So(string(out), ShouldEqual, "[]") 50 }) 51 52 Convey("Should compile FOR i WHILE F() < 10 RETURN i", func() { 53 c := compiler.New() 54 55 counter := -1 56 c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) { 57 counter++ 58 return values.NewInt(counter), nil 59 }) 60 61 p, err := c.Compile(` 62 FOR i WHILE F() < 10 63 RETURN i 64 `) 65 66 So(err, ShouldBeNil) 67 So(p, ShouldHaveSameTypeAs, &runtime.Program{}) 68 69 out, err := p.Run(context.Background()) 70 71 So(err, ShouldBeNil) 72 So(string(out), ShouldEqual, "[0,1,2,3,4,5,6,7,8,9]") 73 }) 74 75 Convey("Should compile FOR i WHILE F() RETURN i", func() { 76 c := compiler.New() 77 78 counter := -1 79 c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) { 80 counter++ 81 82 if counter == 10 { 83 return values.False, nil 84 } 85 86 return values.True, nil 87 }) 88 89 p, err := c.Compile(` 90 FOR i WHILE F() 91 RETURN i 92 `) 93 94 So(err, ShouldBeNil) 95 So(p, ShouldHaveSameTypeAs, &runtime.Program{}) 96 97 out, err := p.Run(context.Background()) 98 99 So(err, ShouldBeNil) 100 So(string(out), ShouldEqual, "[0,1,2,3,4,5,6,7,8,9]") 101 }) 102 103 Convey("Should compile nested FOR operators", func() { 104 c := compiler.New() 105 106 counter := -1 107 c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) { 108 counter++ 109 return values.NewInt(counter), nil 110 }) 111 112 p, err := c.Compile(` 113 FOR i WHILE F() < 5 114 LET y = i + 1 115 FOR x IN 1..y 116 RETURN i * x 117 `) 118 119 So(err, ShouldBeNil) 120 121 out, err := p.Run(context.Background()) 122 123 So(err, ShouldBeNil) 124 125 So(string(out), ShouldEqual, "[0,1,2,2,4,6,3,6,9,12,4,8,12,16,20]") 126 }) 127 }) 128 129 Convey("DO-WHILE", func() { 130 Convey("Should compile FOR i DO WHILE false RETURN i", func() { 131 c := compiler.New() 132 133 p, err := c.Compile(` 134 FOR i DO WHILE false 135 RETURN i 136 `) 137 138 So(err, ShouldBeNil) 139 So(p, ShouldHaveSameTypeAs, &runtime.Program{}) 140 141 out, err := p.Run(context.Background()) 142 143 So(err, ShouldBeNil) 144 So(string(out), ShouldEqual, "[0]") 145 }) 146 147 Convey("Should compile FOR i DO WHILE [] RETURN i", func() { 148 c := compiler.New() 149 150 p, err := c.Compile(` 151 FOR i DO WHILE [] 152 RETURN i 153 `) 154 155 So(err, ShouldBeNil) 156 So(p, ShouldHaveSameTypeAs, &runtime.Program{}) 157 158 out, err := p.Run(context.Background()) 159 160 So(err, ShouldBeNil) 161 So(string(out), ShouldEqual, "[0]") 162 }) 163 164 Convey("Should compile FOR i DO WHILE F() < 10 RETURN i", func() { 165 c := compiler.New() 166 167 counter := -1 168 c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) { 169 counter++ 170 return values.NewInt(counter), nil 171 }) 172 173 p, err := c.Compile(` 174 FOR i DO WHILE F() < 10 175 RETURN i 176 `) 177 178 So(err, ShouldBeNil) 179 So(p, ShouldHaveSameTypeAs, &runtime.Program{}) 180 181 out, err := p.Run(context.Background()) 182 183 So(err, ShouldBeNil) 184 So(string(out), ShouldEqual, "[0,1,2,3,4,5,6,7,8,9,10]") 185 }) 186 187 Convey("Should compile FOR i WHILE F() RETURN i", func() { 188 c := compiler.New() 189 190 counter := -1 191 c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) { 192 counter++ 193 194 if counter == 10 { 195 return values.False, nil 196 } 197 198 return values.True, nil 199 }) 200 201 p, err := c.Compile(` 202 FOR i WHILE F() 203 RETURN i 204 `) 205 206 So(err, ShouldBeNil) 207 So(p, ShouldHaveSameTypeAs, &runtime.Program{}) 208 209 out, err := p.Run(context.Background()) 210 211 So(err, ShouldBeNil) 212 So(string(out), ShouldEqual, "[0,1,2,3,4,5,6,7,8,9]") 213 }) 214 215 Convey("Should compile nested FOR operators", func() { 216 c := compiler.New() 217 218 counter := -1 219 c.RegisterFunction("F", func(ctx context.Context, args ...core.Value) (core.Value, error) { 220 counter++ 221 return values.NewInt(counter), nil 222 }) 223 224 p, err := c.Compile(` 225 FOR i WHILE F() < 5 226 LET y = i + 1 227 FOR x IN 1..y 228 RETURN i * x 229 `) 230 231 So(err, ShouldBeNil) 232 233 out, err := p.Run(context.Background()) 234 235 So(err, ShouldBeNil) 236 237 So(string(out), ShouldEqual, "[0,1,2,2,4,6,3,6,9,12,4,8,12,16,20]") 238 }) 239 }) 240 }) 241 }