1717import static com .google .common .truth .Truth .assertThat ;
1818import static org .junit .Assert .assertThrows ;
1919
20+ import com .google .common .collect .ImmutableList ;
21+ import com .google .common .collect .ImmutableMap ;
22+ import com .google .errorprone .annotations .Immutable ;
23+ import dev .cel .bundle .Cel ;
24+ import dev .cel .bundle .CelFactory ;
25+ import dev .cel .common .CelAbstractSyntaxTree ;
26+ import dev .cel .common .types .CelType ;
27+ import dev .cel .common .types .CelTypeProvider ;
2028import dev .cel .common .types .OpaqueType ;
29+ import java .util .Map ;
30+ import java .util .Optional ;
2131import org .junit .Test ;
2232import org .junit .runner .RunWith ;
2333import org .junit .runners .JUnit4 ;
@@ -37,4 +47,144 @@ public void opaqueValue_construct() {
3747 public void create_nullValue_throws () {
3848 assertThrows (NullPointerException .class , () -> OpaqueValue .create ("opaque_type_name" , null ));
3949 }
50+
51+ private static final OpaqueType CUSTOM_OPAQUE_TYPE = OpaqueType .create ("custom_opaque" );
52+
53+ private static final CelTypeProvider CUSTOM_OPAQUE_TYPE_PROVIDER =
54+ new CelTypeProvider () {
55+ @ Override
56+ public ImmutableList <CelType > types () {
57+ return ImmutableList .of (CUSTOM_OPAQUE_TYPE );
58+ }
59+
60+ @ Override
61+ public Optional <CelType > findType (String typeName ) {
62+ return typeName .equals (CUSTOM_OPAQUE_TYPE .name ())
63+ ? Optional .of (CUSTOM_OPAQUE_TYPE )
64+ : Optional .empty ();
65+ }
66+ };
67+
68+ private static final CelValueProvider CUSTOM_OPAQUE_VALUE_PROVIDER =
69+ new CelValueProvider () {
70+ @ Override
71+ public Optional <Object > newValue (String structType , Map <String , Object > fields ) {
72+ return Optional .empty ();
73+ }
74+
75+ @ Override
76+ public CelValueConverter celValueConverter () {
77+ return new CelValueConverter () {
78+ @ Override
79+ public Object toRuntimeValue (Object value ) {
80+ if (value instanceof CustomOpaqueObject ) {
81+ return new CelCustomOpaqueValue ((CustomOpaqueObject ) value );
82+ }
83+ return super .toRuntimeValue (value );
84+ }
85+ };
86+ }
87+ };
88+
89+ private static final CelValueProvider CUSTOM_OPAQUE_VALUE_PROVIDER_USING_CREATE =
90+ new CelValueProvider () {
91+ @ Override
92+ public Optional <Object > newValue (String structType , Map <String , Object > fields ) {
93+ return Optional .empty ();
94+ }
95+
96+ @ Override
97+ public CelValueConverter celValueConverter () {
98+ return new CelValueConverter () {
99+ @ Override
100+ public Object toRuntimeValue (Object value ) {
101+ if (value instanceof CustomOpaqueObject ) {
102+ return OpaqueValue .create (CUSTOM_OPAQUE_TYPE .name (), value );
103+ }
104+ return super .toRuntimeValue (value );
105+ }
106+ };
107+ }
108+ };
109+
110+ @ Immutable
111+ private static class CustomOpaqueObject {
112+ private final String value ;
113+
114+ CustomOpaqueObject (String value ) {
115+ this .value = value ;
116+ }
117+
118+ String getValue () {
119+ return value ;
120+ }
121+ }
122+
123+ private static class CelCustomOpaqueValue extends OpaqueValue {
124+ private final CustomOpaqueObject obj ;
125+
126+ CelCustomOpaqueValue (CustomOpaqueObject obj ) {
127+ this .obj = obj ;
128+ }
129+
130+ @ Override
131+ public CustomOpaqueObject value () {
132+ return obj ;
133+ }
134+
135+ @ Override
136+ public OpaqueType celType () {
137+ return CUSTOM_OPAQUE_TYPE ;
138+ }
139+ }
140+
141+ @ Test
142+ public void evaluate_customOpaqueValue_asVariable () throws Exception {
143+ Cel cel =
144+ CelFactory .plannerCelBuilder ()
145+ .addVar ("a" , CUSTOM_OPAQUE_TYPE )
146+ .setTypeProvider (CUSTOM_OPAQUE_TYPE_PROVIDER )
147+ .setValueProvider (CUSTOM_OPAQUE_VALUE_PROVIDER )
148+ .build ();
149+ CelAbstractSyntaxTree ast = cel .compile ("a" ).getAst ();
150+
151+ CustomOpaqueObject rawValue = new CustomOpaqueObject ("hello" );
152+ Object result = cel .createProgram (ast ).eval (ImmutableMap .of ("a" , rawValue ));
153+
154+ assertThat (result ).isInstanceOf (CustomOpaqueObject .class );
155+ assertThat (((CustomOpaqueObject ) result ).getValue ()).isEqualTo ("hello" );
156+ }
157+
158+ @ Test
159+ public void evaluate_typeOfCustomOpaqueValue () throws Exception {
160+ Cel cel =
161+ CelFactory .plannerCelBuilder ()
162+ .addVar ("a" , CUSTOM_OPAQUE_TYPE )
163+ .setTypeProvider (CUSTOM_OPAQUE_TYPE_PROVIDER )
164+ .setValueProvider (CUSTOM_OPAQUE_VALUE_PROVIDER )
165+ .build ();
166+ CelAbstractSyntaxTree ast = cel .compile ("type(a) == custom_opaque" ).getAst ();
167+
168+ CustomOpaqueObject rawValue = new CustomOpaqueObject ("hello" );
169+ Object result = cel .createProgram (ast ).eval (ImmutableMap .of ("a" , rawValue ));
170+
171+ assertThat (result ).isEqualTo (true );
172+ }
173+
174+ @ Test
175+ public void evaluate_typeOfCustomOpaqueValue_usingCreate () throws Exception {
176+ Cel cel =
177+ CelFactory .plannerCelBuilder ()
178+ .addVar ("a" , CUSTOM_OPAQUE_TYPE )
179+ .setTypeProvider (CUSTOM_OPAQUE_TYPE_PROVIDER )
180+ .setValueProvider (CUSTOM_OPAQUE_VALUE_PROVIDER_USING_CREATE )
181+ .build ();
182+ CelAbstractSyntaxTree ast = cel .compile ("type(a) == custom_opaque" ).getAst ();
183+
184+ CustomOpaqueObject rawValue = new CustomOpaqueObject ("hello" );
185+ Object result = cel .createProgram (ast ).eval (ImmutableMap .of ("a" , rawValue ));
186+
187+ assertThat (result ).isEqualTo (true );
188+ }
40189}
190+
0 commit comments