15
15
package cel
16
16
17
17
import (
18
+ "context"
18
19
"fmt"
19
20
"io/ioutil"
20
21
"log"
21
22
"sync"
22
23
"testing"
24
+ "time"
23
25
24
26
"github.com/golang/protobuf/proto"
25
27
"github.com/google/cel-go/checker/decls"
@@ -32,6 +34,7 @@ import (
32
34
"github.com/google/cel-go/interpreter"
33
35
"github.com/google/cel-go/interpreter/functions"
34
36
"github.com/google/cel-go/parser"
37
+ "github.com/google/cel-go/test"
35
38
36
39
descpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
37
40
proto2pb "github.com/google/cel-go/test/proto2pb"
@@ -876,3 +879,98 @@ func Test_CustomInterpreterDecorator(t *testing.T) {
876
879
t .Errorf ("got %v as the last observed constant, wanted 1" , lastConst )
877
880
}
878
881
}
882
+
883
+ func Test_AsyncExtension (t * testing.T ) {
884
+ env , err := NewEnv (
885
+ Declarations (
886
+ decls .NewVar ("x" , decls .String ),
887
+ decls .NewFunction ("asyncEcho" ,
888
+ decls .NewOverload (
889
+ "async_echo_string" ,
890
+ []* exprpb.Type {decls .String },
891
+ decls .String )),
892
+ ),
893
+ )
894
+ if err != nil {
895
+ t .Fatal (err )
896
+ }
897
+ funcs := Functions (
898
+ & functions.Overload {
899
+ Operator : "asyncEcho" ,
900
+ Async : test .FakeRPC (25 * time .Millisecond ),
901
+ },
902
+ & functions.Overload {
903
+ Operator : "async_echo_string" ,
904
+ Async : test .FakeRPC (25 * time .Millisecond ),
905
+ },
906
+ )
907
+
908
+ tests := []struct {
909
+ expr string
910
+ parseOnly bool
911
+ evalOpts EvalOption
912
+ out ref.Val
913
+ }{
914
+ {
915
+ expr : `asyncEcho(x)` ,
916
+ out : types .String ("async echo success!" ),
917
+ },
918
+ {
919
+ expr : `asyncEcho(x)` ,
920
+ parseOnly : true ,
921
+ out : types .String ("async echo success!" ),
922
+ },
923
+ {
924
+ expr : `asyncEcho(x)` ,
925
+ evalOpts : OptOptimize ,
926
+ out : types .String ("async echo success!" ),
927
+ },
928
+ {
929
+ expr : `asyncEcho(x) == 'async echo success!'` ,
930
+ evalOpts : OptOptimize | OptTrackState ,
931
+ out : types .True ,
932
+ },
933
+ {
934
+ expr : `asyncEcho(x) == 'async echo success!' || true` ,
935
+ evalOpts : OptOptimize | OptTrackState ,
936
+ out : types .True ,
937
+ },
938
+ }
939
+ for i , tst := range tests {
940
+ tc := tst
941
+ t .Run (fmt .Sprintf ("%d" , i ), func (tt * testing.T ) {
942
+ var ast * Ast
943
+ var iss * Issues
944
+ if tc .parseOnly {
945
+ ast , iss = env .Parse (tc .expr )
946
+ } else {
947
+ ast , iss = env .Compile (tc .expr )
948
+ }
949
+ if iss .Err () != nil {
950
+ tt .Fatal (iss .Err ())
951
+ }
952
+ opts := []ProgramOption {funcs }
953
+ if tc .evalOpts != 0 {
954
+ opts = append (opts , EvalOptions (tc .evalOpts ))
955
+ }
956
+ prg , err := env .AsyncProgram (ast , opts ... )
957
+ if err != nil {
958
+ tt .Fatal (err )
959
+ }
960
+ ctx := context .TODO ()
961
+ out , det , err := prg .AsyncEval (ctx , map [string ]interface {}{
962
+ "x" : "async echo" ,
963
+ })
964
+ if err != nil {
965
+ tt .Fatal (err )
966
+ }
967
+ if out .Equal (tc .out ) != types .True {
968
+ tt .Errorf ("got %v, wanted %v" , out , tc .out )
969
+ }
970
+ if tc .evalOpts & OptTrackState == OptTrackState && det == nil {
971
+ tt .Error ("details was nil, expected non-nil" )
972
+ }
973
+ })
974
+ }
975
+
976
+ }
0 commit comments