@@ -219,3 +219,143 @@ func TestExpression_EvaluateBoolean(t *testing.T) {
219
219
})
220
220
}
221
221
}
222
+
223
+ func TestExpression_EvaluateString (t * testing.T ) {
224
+ for _ , tt := range []struct {
225
+ name string
226
+ expr string
227
+ opts []cel.Option
228
+ data map [string ]any
229
+ result string
230
+ err string
231
+ }{
232
+ {
233
+ name : "non-existent field" ,
234
+ expr : "foo" ,
235
+ data : map [string ]any {},
236
+ err : "failed to evaluate the CEL expression 'foo': no such attribute(s): foo" ,
237
+ },
238
+ {
239
+ name : "string field" ,
240
+ expr : "foo" ,
241
+ data : map [string ]any {"foo" : "some-value" },
242
+ result : "some-value" ,
243
+ },
244
+ {
245
+ name : "non-string field" ,
246
+ expr : "foo" ,
247
+ data : map [string ]any {"foo" : 123 },
248
+ err : "failed to evaluate CEL expression as string: 'foo'" ,
249
+ },
250
+ {
251
+ name : "nested string field" ,
252
+ expr : "foo.bar" ,
253
+ data : map [string ]any {"foo" : map [string ]any {"bar" : "some-value" }},
254
+ result : "some-value" ,
255
+ },
256
+ {
257
+ name : "compiled expression returning string" ,
258
+ expr : "foo.bar" ,
259
+ opts : []cel.Option {cel .WithCompile (), cel .WithStructVariables ("foo" )},
260
+ data : map [string ]any {"foo" : map [string ]any {"bar" : "some-value" }},
261
+ result : "some-value" ,
262
+ },
263
+ {
264
+ name : "compiled expression returning string multiple variables" ,
265
+ expr : "foo.bar + '/' + foo.baz + '/' + bar.biz" ,
266
+ opts : []cel.Option {
267
+ cel .WithCompile (),
268
+ cel .WithStructVariables ("foo" , "bar" ),
269
+ },
270
+ data : map [string ]any {
271
+ "foo" : map [string ]any {
272
+ "bar" : "some-value" ,
273
+ "baz" : "some-other-value" },
274
+ "bar" : map [string ]any {
275
+ "biz" : "some-third-value" ,
276
+ },
277
+ },
278
+ result : "some-value/some-other-value/some-third-value" ,
279
+ },
280
+ {
281
+ name : "compiled expression with string manipulation and zero index" ,
282
+ expr : "foo.bar + '/' + foo.baz + '/' + bar.uid.split('-')[0].lowerAscii()" ,
283
+ opts : []cel.Option {
284
+ cel .WithCompile (),
285
+ cel .WithStructVariables ("foo" , "bar" ),
286
+ },
287
+ data : map [string ]any {
288
+ "foo" : map [string ]any {
289
+ "bar" : "some-value" ,
290
+ "baz" : "some-other-value" },
291
+ "bar" : map [string ]any {
292
+ "uid" : "AKS2J23-DAFLSDD-123J5LS" ,
293
+ },
294
+ },
295
+ result : "some-value/some-other-value/aks2j23" ,
296
+ },
297
+ {
298
+ name : "compiled expression with string manipulation and first" ,
299
+ expr : "foo.bar + '/' + foo.baz + '/' + bar.uid.split('-').first().value().lowerAscii()" ,
300
+ opts : []cel.Option {
301
+ cel .WithCompile (),
302
+ cel .WithStructVariables ("foo" , "bar" ),
303
+ },
304
+ data : map [string ]any {
305
+ "foo" : map [string ]any {
306
+ "bar" : "some-value" ,
307
+ "baz" : "some-other-value" },
308
+ "bar" : map [string ]any {
309
+ "uid" : "AKS2J23-DAFLSDD-123J5LS" ,
310
+ },
311
+ },
312
+ result : "some-value/some-other-value/aks2j23" ,
313
+ },
314
+ {
315
+ name : "compiled expression with first" ,
316
+ expr : "foo.bar.split('-').first().value()" ,
317
+ opts : []cel.Option {cel .WithCompile (), cel .WithStructVariables ("foo" )},
318
+ data : map [string ]any {
319
+ "foo" : map [string ]any {"bar" : "hello-world-testing-123" },
320
+ },
321
+ result : "hello" ,
322
+ },
323
+ {
324
+ name : "compiled expression with last" ,
325
+ expr : "foo.bar.split('-').last().value()" ,
326
+ opts : []cel.Option {cel .WithCompile (), cel .WithStructVariables ("foo" )},
327
+ data : map [string ]any {
328
+ "foo" : map [string ]any {"bar" : "hello-world-testing-123" },
329
+ },
330
+ result : "123" ,
331
+ },
332
+ {
333
+ name : "error without value method" ,
334
+ expr : "foo.bar.split('-').first()" ,
335
+ opts : []cel.Option {cel .WithCompile (), cel .WithStructVariables ("foo" )},
336
+ data : map [string ]any {
337
+ "foo" : map [string ]any {"bar" : "hello-world-testing-123" },
338
+ },
339
+ err : "failed to evaluate CEL expression as string: 'foo.bar.split('-').first()'" ,
340
+ },
341
+ } {
342
+ t .Run (tt .name , func (t * testing.T ) {
343
+ t .Parallel ()
344
+
345
+ g := NewWithT (t )
346
+
347
+ e , err := cel .NewExpression (tt .expr , tt .opts ... )
348
+ g .Expect (err ).NotTo (HaveOccurred ())
349
+
350
+ result , err := e .EvaluateString (context .Background (), tt .data )
351
+
352
+ if tt .err != "" {
353
+ g .Expect (err ).To (HaveOccurred ())
354
+ g .Expect (err .Error ()).To (ContainSubstring (tt .err ))
355
+ } else {
356
+ g .Expect (err ).NotTo (HaveOccurred ())
357
+ g .Expect (result ).To (Equal (tt .result ))
358
+ }
359
+ })
360
+ }
361
+ }
0 commit comments