@@ -17,6 +17,79 @@ import (
1717 "github.com/expr-lang/expr/parser"
1818)
1919
20+ func TestOptimize (t * testing.T ) {
21+ env := map [string ]any {
22+ "a" : 1 ,
23+ "b" : 2 ,
24+ "c" : 3 ,
25+ }
26+
27+ tests := []struct {
28+ expr string
29+ want any
30+ }{
31+ {`1 + 2` , 3 },
32+ {`sum([])` , 0 },
33+ {`sum([a])` , 1 },
34+ {`sum([a, b])` , 3 },
35+ {`sum([a, b, c])` , 6 },
36+ {`sum([a, b, c, 4])` , 10 },
37+ {`all(1..3, {# > 0}) && all(1..3, {# < 4})` , true },
38+ {`all(1..3, {# > 2}) && all(1..3, {# < 4})` , false },
39+ {`all(1..3, {# > 0}) && all(1..3, {# < 2})` , false },
40+ {`all(1..3, {# > 2}) && all(1..3, {# < 2})` , false },
41+ {`all(1..3, {# > 0}) || all(1..3, {# < 4})` , true },
42+ {`all(1..3, {# > 0}) || all(1..3, {# != 2})` , true },
43+ {`all(1..3, {# != 3}) || all(1..3, {# < 4})` , true },
44+ {`all(1..3, {# != 3}) || all(1..3, {# != 2})` , false },
45+ {`none(1..3, {# == 0})` , true },
46+ {`none(1..3, {# == 0}) && none(1..3, {# == 4})` , true },
47+ {`none(1..3, {# == 0}) && none(1..3, {# == 3})` , false },
48+ {`none(1..3, {# == 1}) && none(1..3, {# == 4})` , false },
49+ {`none(1..3, {# == 1}) && none(1..3, {# == 3})` , false },
50+ {`none(1..3, {# == 0}) || none(1..3, {# == 4})` , true },
51+ {`none(1..3, {# == 0}) || none(1..3, {# == 3})` , true },
52+ {`none(1..3, {# == 1}) || none(1..3, {# == 4})` , true },
53+ {`none(1..3, {# == 1}) || none(1..3, {# == 3})` , false },
54+ {`any([1, 1, 0, 1], {# == 0})` , true },
55+ {`any(1..3, {# == 1}) && any(1..3, {# == 2})` , true },
56+ {`any(1..3, {# == 0}) && any(1..3, {# == 2})` , false },
57+ {`any(1..3, {# == 1}) && any(1..3, {# == 4})` , false },
58+ {`any(1..3, {# == 0}) && any(1..3, {# == 4})` , false },
59+ {`any(1..3, {# == 1}) || any(1..3, {# == 2})` , true },
60+ {`any(1..3, {# == 0}) || any(1..3, {# == 2})` , true },
61+ {`any(1..3, {# == 1}) || any(1..3, {# == 4})` , true },
62+ {`any(1..3, {# == 0}) || any(1..3, {# == 4})` , false },
63+ {`one([1, 1, 0, 1], {# == 0}) and not one([1, 0, 0, 1], {# == 0})` , true },
64+ {`one(1..3, {# == 1}) and one(1..3, {# == 2})` , true },
65+ {`one(1..3, {# == 1 || # == 2}) and one(1..3, {# == 2})` , false },
66+ {`one(1..3, {# == 1}) and one(1..3, {# == 2 || # == 3})` , false },
67+ {`one(1..3, {# == 1 || # == 2}) and one(1..3, {# == 2 || # == 3})` , false },
68+ {`one(1..3, {# == 1}) or one(1..3, {# == 2})` , true },
69+ {`one(1..3, {# == 1 || # == 2}) or one(1..3, {# == 2})` , true },
70+ {`one(1..3, {# == 1}) or one(1..3, {# == 2 || # == 3})` , true },
71+ {`one(1..3, {# == 1 || # == 2}) or one(1..3, {# == 2 || # == 3})` , false },
72+ }
73+
74+ for _ , tt := range tests {
75+ t .Run (tt .expr , func (t * testing.T ) {
76+ program , err := expr .Compile (tt .expr , expr .Env (env ))
77+ require .NoError (t , err )
78+
79+ output , err := expr .Run (program , env )
80+ require .NoError (t , err )
81+ assert .Equal (t , tt .want , output )
82+
83+ unoptimizedProgram , err := expr .Compile (tt .expr , expr .Env (env ), expr .Optimize (false ))
84+ require .NoError (t , err )
85+
86+ unoptimizedOutput , err := expr .Run (unoptimizedProgram , env )
87+ require .NoError (t , err )
88+ assert .Equal (t , tt .want , unoptimizedOutput )
89+ })
90+ }
91+ }
92+
2093func TestOptimize_constant_folding (t * testing.T ) {
2194 tree , err := parser .Parse (`[1,2,3][5*5-25]` )
2295 require .NoError (t , err )
0 commit comments