github.com/MontFerret/ferret@v0.18.0/pkg/compiler/compiler_collect_aggregate_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 ) 12 13 func TestAggregate(t *testing.T) { 14 Convey("Should aggregate values without grouping", t, func() { 15 c := compiler.New() 16 17 prog, err := c.Compile(` 18 LET users = [ 19 { 20 active: true, 21 married: true, 22 age: 31, 23 gender: "m" 24 }, 25 { 26 active: true, 27 married: false, 28 age: 25, 29 gender: "f" 30 }, 31 { 32 active: true, 33 married: false, 34 age: 36, 35 gender: "m" 36 }, 37 { 38 active: false, 39 married: true, 40 age: 69, 41 gender: "m" 42 }, 43 { 44 active: true, 45 married: true, 46 age: 45, 47 gender: "f" 48 } 49 ] 50 FOR u IN users 51 COLLECT AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age) 52 RETURN { 53 minAge, 54 maxAge 55 } 56 `) 57 58 So(err, ShouldBeNil) 59 So(prog, ShouldHaveSameTypeAs, &runtime.Program{}) 60 61 out, err := prog.Run(context.Background()) 62 63 So(err, ShouldBeNil) 64 So(string(out), ShouldEqual, `[{"maxAge":69,"minAge":25}]`) 65 }) 66 67 Convey("Should aggregate values without grouping with multiple arguments", t, func() { 68 c := compiler.New() 69 70 prog, err := c.Compile(` 71 LET users = [ 72 { 73 active: true, 74 married: true, 75 age: 31, 76 gender: "m" 77 }, 78 { 79 active: true, 80 married: false, 81 age: 25, 82 gender: "f" 83 }, 84 { 85 active: true, 86 married: false, 87 age: 36, 88 gender: "m" 89 }, 90 { 91 active: false, 92 married: true, 93 age: 69, 94 gender: "m" 95 }, 96 { 97 active: true, 98 married: true, 99 age: 45, 100 gender: "f" 101 } 102 ] 103 FOR u IN users 104 COLLECT AGGREGATE ages = UNION(u.age, u.age) 105 RETURN ages 106 `) 107 108 So(err, ShouldBeNil) 109 So(prog, ShouldHaveSameTypeAs, &runtime.Program{}) 110 111 out, err := prog.Run(context.Background()) 112 113 So(err, ShouldBeNil) 114 So(string(out), ShouldEqual, `[[31,25,36,69,45,31,25,36,69,45]]`) 115 }) 116 117 Convey("Should aggregate values with grouping", t, func() { 118 c := compiler.New() 119 120 prog, err := c.Compile(` 121 LET users = [ 122 { 123 active: true, 124 married: true, 125 age: 31, 126 gender: "m" 127 }, 128 { 129 active: true, 130 married: false, 131 age: 25, 132 gender: "f" 133 }, 134 { 135 active: true, 136 married: false, 137 age: 36, 138 gender: "m" 139 }, 140 { 141 active: false, 142 married: true, 143 age: 69, 144 gender: "m" 145 }, 146 { 147 active: true, 148 married: true, 149 age: 45, 150 gender: "f" 151 } 152 ] 153 FOR u IN users 154 COLLECT ageGroup = FLOOR(u.age / 5) * 5 155 AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age) 156 RETURN { 157 ageGroup, 158 minAge, 159 maxAge 160 } 161 `) 162 163 So(err, ShouldBeNil) 164 So(prog, ShouldHaveSameTypeAs, &runtime.Program{}) 165 166 out, err := prog.Run(context.Background()) 167 168 So(err, ShouldBeNil) 169 So(string(out), ShouldEqual, `[{"ageGroup":25,"maxAge":25,"minAge":25},{"ageGroup":30,"maxAge":31,"minAge":31},{"ageGroup":35,"maxAge":36,"minAge":36},{"ageGroup":45,"maxAge":45,"minAge":45},{"ageGroup":65,"maxAge":69,"minAge":69}]`) 170 }) 171 } 172 173 func BenchmarkAggregate(b *testing.B) { 174 p := compiler.New().MustCompile(` 175 LET users = [ 176 { 177 active: true, 178 married: true, 179 age: 31, 180 gender: "m" 181 }, 182 { 183 active: true, 184 married: false, 185 age: 25, 186 gender: "f" 187 }, 188 { 189 active: true, 190 married: false, 191 age: 36, 192 gender: "m" 193 }, 194 { 195 active: false, 196 married: true, 197 age: 69, 198 gender: "m" 199 }, 200 { 201 active: true, 202 married: true, 203 age: 45, 204 gender: "f" 205 } 206 ] 207 FOR u IN users 208 COLLECT AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age) 209 RETURN { 210 minAge, 211 maxAge 212 } 213 `) 214 215 for n := 0; n < b.N; n++ { 216 p.Run(context.Background()) 217 } 218 } 219 220 func BenchmarkAggregate2(b *testing.B) { 221 p := compiler.New().MustCompile(` 222 LET users = [ 223 { 224 active: true, 225 married: true, 226 age: 31, 227 gender: "m" 228 }, 229 { 230 active: true, 231 married: false, 232 age: 25, 233 gender: "f" 234 }, 235 { 236 active: true, 237 married: false, 238 age: 36, 239 gender: "m" 240 }, 241 { 242 active: false, 243 married: true, 244 age: 69, 245 gender: "m" 246 }, 247 { 248 active: true, 249 married: true, 250 age: 45, 251 gender: "f" 252 } 253 ] 254 FOR u IN users 255 COLLECT AGGREGATE ages = UNION(u.age, u.age) 256 RETURN ages 257 `) 258 259 for n := 0; n < b.N; n++ { 260 p.Run(context.Background()) 261 } 262 } 263 264 func BenchmarkAggregate3(b *testing.B) { 265 p := compiler.New().MustCompile(` 266 LET users = [ 267 { 268 active: true, 269 married: true, 270 age: 31, 271 gender: "m" 272 }, 273 { 274 active: true, 275 married: false, 276 age: 25, 277 gender: "f" 278 }, 279 { 280 active: true, 281 married: false, 282 age: 36, 283 gender: "m" 284 }, 285 { 286 active: false, 287 married: true, 288 age: 69, 289 gender: "m" 290 }, 291 { 292 active: true, 293 married: true, 294 age: 45, 295 gender: "f" 296 } 297 ] 298 FOR u IN users 299 COLLECT ageGroup = FLOOR(u.age / 5) * 5 300 AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age) 301 RETURN { 302 ageGroup, 303 minAge, 304 maxAge 305 } 306 `) 307 308 for n := 0; n < b.N; n++ { 309 p.Run(context.Background()) 310 } 311 }