| 162 | } |
| 163 | |
| 164 | func TestListsVersion(t *testing.T) { |
| 165 | versionCases := []struct { |
| 166 | version uint32 |
| 167 | supportedFunctions map[string]string |
| 168 | }{ |
| 169 | { |
| 170 | version: 0, |
| 171 | supportedFunctions: map[string]string{ |
| 172 | "slice": "[1, 2, 3, 4, 5].slice(2, 4) == [3, 4]", |
| 173 | }, |
| 174 | }, |
| 175 | { |
| 176 | version: 1, |
| 177 | supportedFunctions: map[string]string{ |
| 178 | "flatten": "[[1, 2], [3, 4]].flatten() == [1, 2, 3, 4]", |
| 179 | }, |
| 180 | }, |
| 181 | { |
| 182 | version: 2, |
| 183 | supportedFunctions: map[string]string{ |
| 184 | "distinct": "[1, 2, 2, 1].distinct() == [1, 2]", |
| 185 | "range": "lists.range(5) == [0, 1, 2, 3, 4]", |
| 186 | "reverse": "[1, 2, 3].reverse() == [3, 2, 1]", |
| 187 | "sort": "[2, 1, 3].sort() == [1, 2, 3]", |
| 188 | "sortBy": "[{'field': 'lo'}, {'field': 'hi'}].sortBy(m, m.field) == [{'field': 'hi'}, {'field': 'lo'}]", |
| 189 | }, |
| 190 | }, |
| 191 | } |
| 192 | for _, lib := range versionCases { |
| 193 | env, err := cel.NewEnv(Lists(ListsVersion(lib.version))) |
| 194 | if err != nil { |
| 195 | t.Fatalf("cel.NewEnv(Lists(ListsVersion(%d))) failed: %v", lib.version, err) |
| 196 | } |
| 197 | t.Run(fmt.Sprintf("version=%d", lib.version), func(t *testing.T) { |
| 198 | for _, tc := range versionCases { |
| 199 | for name, expr := range tc.supportedFunctions { |
| 200 | supported := lib.version >= tc.version |
| 201 | t.Run(fmt.Sprintf("%s-supported=%t", name, supported), func(t *testing.T) { |
| 202 | ast, iss := env.Compile(expr) |
| 203 | if supported { |
| 204 | if iss.Err() != nil { |
| 205 | t.Errorf("unexpected error: %v", iss.Err()) |
| 206 | } |
| 207 | } else { |
| 208 | if iss.Err() == nil || !strings.Contains(iss.Err().Error(), "undeclared reference") { |
| 209 | t.Errorf("got error %v, wanted error %s for expr: %s, version: %d", iss.Err(), "undeclared reference", expr, tc.version) |
| 210 | } |
| 211 | return |
| 212 | } |
| 213 | prg, err := env.Program(ast) |
| 214 | if err != nil { |
| 215 | t.Fatalf("env.Program() failed: %v", err) |
| 216 | } |
| 217 | out, _, err := prg.Eval(cel.NoVars()) |
| 218 | if err != nil { |
| 219 | t.Fatalf("prg.Eval() failed: %v", err) |
| 220 | } |
| 221 | if out != types.True { |