Skip to content

Commit 2ecc629

Browse files
l46kokcopybara-github
authored andcommitted
Add parsed-only evaluation test coverage to Regex Extensions
PiperOrigin-RevId: 899219077
1 parent 664c31b commit 2ecc629

11 files changed

Lines changed: 393 additions & 372 deletions

File tree

bundle/src/test/java/dev/cel/bundle/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ java_library(
1717
deps = [
1818
"//:java_truth",
1919
"//bundle:cel",
20-
"//bundle:cel_experimental_factory",
2120
"//bundle:cel_impl",
2221
"//bundle:environment",
2322
"//bundle:environment_exception",
@@ -56,6 +55,7 @@ java_library(
5655
"//runtime:evaluation_listener",
5756
"//runtime:function_binding",
5857
"//runtime:unknown_attributes",
58+
"//testing:cel_runtime_flavor",
5959
"//testing/protos:single_file_extension_java_proto",
6060
"//testing/protos:single_file_java_proto",
6161
"@cel_spec//proto/cel/expr:checked_java_proto",

bundle/src/test/java/dev/cel/bundle/CelImplTest.java

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
import dev.cel.runtime.CelUnknownSet;
115115
import dev.cel.runtime.CelVariableResolver;
116116
import dev.cel.runtime.UnknownContext;
117+
import dev.cel.testing.CelRuntimeFlavor;
117118
import dev.cel.testing.testdata.SingleFile;
118119
import dev.cel.testing.testdata.SingleFileExtensionsProto;
119120
import dev.cel.testing.testdata.proto3.StandaloneGlobalEnum;
@@ -2144,8 +2145,9 @@ public void toBuilder_isImmutable() {
21442145
}
21452146

21462147
@Test
2147-
public void eval_withJsonFieldName(@TestParameter RuntimeEnv runtimeEnv) throws Exception {
2148-
Cel cel = runtimeEnv.cel;
2148+
public void eval_withJsonFieldName(@TestParameter CelRuntimeFlavor runtimeFlavor)
2149+
throws Exception {
2150+
Cel cel = setupEnv(runtimeFlavor.builder());
21492151
CelAbstractSyntaxTree ast =
21502152
cel.compile(
21512153
"file.int32_snake_case_json_name == 1 && "
@@ -2176,8 +2178,9 @@ public void eval_withJsonFieldName(@TestParameter RuntimeEnv runtimeEnv) throws
21762178
}
21772179

21782180
@Test
2179-
public void eval_withJsonFieldName_fieldsFallBack(@TestParameter RuntimeEnv runtimeEnv) throws Exception {
2180-
Cel cel = runtimeEnv.cel;
2181+
public void eval_withJsonFieldName_fieldsFallBack(@TestParameter CelRuntimeFlavor runtimeFlavor)
2182+
throws Exception {
2183+
Cel cel = setupEnv(runtimeFlavor.builder());
21812184
CelAbstractSyntaxTree ast =
21822185
cel.compile(
21832186
"dyn(file).int32_snake_case_json_name == 1 && "
@@ -2206,8 +2209,9 @@ public void eval_withJsonFieldName_fieldsFallBack(@TestParameter RuntimeEnv runt
22062209
}
22072210

22082211
@Test
2209-
public void eval_withJsonFieldName_extensionFields(@TestParameter RuntimeEnv runtimeEnv) throws Exception {
2210-
Cel cel = runtimeEnv.cel;
2212+
public void eval_withJsonFieldName_extensionFields(@TestParameter CelRuntimeFlavor runtimeFlavor)
2213+
throws Exception {
2214+
Cel cel = setupEnv(runtimeFlavor.builder());
22112215
CelAbstractSyntaxTree ast =
22122216
cel.compile(
22132217
"proto.getExt(file, dev.cel.testing.testdata.int64CamelCaseJsonName) == 5 &&"
@@ -2317,33 +2321,21 @@ private static TypeProvider aliasingProvider(ImmutableMap<String, Type> typeAlia
23172321
};
23182322
}
23192323

2320-
private enum RuntimeEnv {
2321-
LEGACY(setupEnv(CelFactory.standardCelBuilder())),
2322-
PLANNER(setupEnv(CelExperimentalFactory.plannerCelBuilder()))
2323-
;
2324-
2325-
private final Cel cel;
2326-
2327-
private static Cel setupEnv(CelBuilder celBuilder) {
2328-
ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
2329-
SingleFileExtensionsProto.registerAllExtensions(extensionRegistry);
2330-
return celBuilder
2331-
.addVar("file", StructTypeReference.create(SingleFile.getDescriptor().getFullName()))
2332-
.addMessageTypes(SingleFile.getDescriptor())
2333-
.addFileTypes(SingleFileExtensionsProto.getDescriptor())
2334-
.addCompilerLibraries(CelExtensions.protos())
2335-
.setExtensionRegistry(extensionRegistry)
2336-
.setOptions(
2337-
CelOptions.current()
2338-
.enableJsonFieldNames(true)
2339-
.enableHeterogeneousNumericComparisons(true)
2340-
.enableQuotedIdentifierSyntax(true)
2341-
.build())
2342-
.build();
2343-
}
2344-
2345-
RuntimeEnv(Cel cel) {
2346-
this.cel = cel;
2347-
}
2324+
private static Cel setupEnv(CelBuilder celBuilder) {
2325+
ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
2326+
SingleFileExtensionsProto.registerAllExtensions(extensionRegistry);
2327+
return celBuilder
2328+
.addVar("file", StructTypeReference.create(SingleFile.getDescriptor().getFullName()))
2329+
.addMessageTypes(SingleFile.getDescriptor())
2330+
.addFileTypes(SingleFileExtensionsProto.getDescriptor())
2331+
.addCompilerLibraries(CelExtensions.protos())
2332+
.setExtensionRegistry(extensionRegistry)
2333+
.setOptions(
2334+
CelOptions.current()
2335+
.enableJsonFieldNames(true)
2336+
.enableHeterogeneousNumericComparisons(true)
2337+
.enableQuotedIdentifierSyntax(true)
2338+
.build())
2339+
.build();
23482340
}
23492341
}

extensions/src/main/java/dev/cel/extensions/CelComprehensionsExtensions.java

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -118,29 +118,18 @@ public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) {
118118
@Override
119119
public void setRuntimeOptions(
120120
CelRuntimeBuilder runtimeBuilder, RuntimeEquality runtimeEquality, CelOptions celOptions) {
121-
for (Function function : functions) {
122-
for (CelOverloadDecl overload : function.functionDecl.overloads()) {
123-
switch (overload.overloadId()) {
124-
case MAP_INSERT_OVERLOAD_MAP_MAP:
125-
runtimeBuilder.addFunctionBindings(
126-
CelFunctionBinding.from(
127-
MAP_INSERT_OVERLOAD_MAP_MAP,
128-
Map.class,
129-
Map.class,
130-
(map1, map2) -> mapInsertMap(map1, map2, runtimeEquality)));
131-
break;
132-
case MAP_INSERT_OVERLOAD_KEY_VALUE:
133-
runtimeBuilder.addFunctionBindings(
134-
CelFunctionBinding.from(
135-
MAP_INSERT_OVERLOAD_KEY_VALUE,
136-
ImmutableList.of(Map.class, Object.class, Object.class),
137-
args -> mapInsertKeyValue(args, runtimeEquality)));
138-
break;
139-
default:
140-
// Nothing to add.
141-
}
142-
}
143-
}
121+
runtimeBuilder.addFunctionBindings(
122+
CelFunctionBinding.fromOverloads(
123+
MAP_INSERT_FUNCTION,
124+
CelFunctionBinding.from(
125+
MAP_INSERT_OVERLOAD_MAP_MAP,
126+
Map.class,
127+
Map.class,
128+
(map1, map2) -> mapInsertMap(map1, map2, runtimeEquality)),
129+
CelFunctionBinding.from(
130+
MAP_INSERT_OVERLOAD_KEY_VALUE,
131+
ImmutableList.of(Map.class, Object.class, Object.class),
132+
args -> mapInsertKeyValue(args, runtimeEquality))));
144133
}
145134

146135
@Override

extensions/src/test/java/dev/cel/extensions/CelRegexExtensionsTest.java

Lines changed: 39 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,38 @@
2020
import com.google.testing.junit.testparameterinjector.TestParameter;
2121
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
2222
import com.google.testing.junit.testparameterinjector.TestParameters;
23+
import dev.cel.bundle.Cel;
2324
import dev.cel.common.CelAbstractSyntaxTree;
2425
import dev.cel.common.CelFunctionDecl;
2526
import dev.cel.common.CelOptions;
26-
import dev.cel.compiler.CelCompiler;
27-
import dev.cel.compiler.CelCompilerFactory;
2827
import dev.cel.runtime.CelEvaluationException;
29-
import dev.cel.runtime.CelRuntime;
30-
import dev.cel.runtime.CelRuntimeFactory;
28+
import dev.cel.testing.CelRuntimeFlavor;
3129
import java.util.Optional;
30+
import org.junit.Assume;
31+
import org.junit.Before;
3232
import org.junit.Test;
3333
import org.junit.runner.RunWith;
3434

3535
@RunWith(TestParameterInjector.class)
3636
public final class CelRegexExtensionsTest {
3737

38-
private static final CelCompiler COMPILER =
39-
CelCompilerFactory.standardCelCompilerBuilder().addLibraries(CelExtensions.regex()).build();
40-
private static final CelRuntime RUNTIME =
41-
CelRuntimeFactory.standardCelRuntimeBuilder().addLibraries(CelExtensions.regex()).build();
38+
@TestParameter public CelRuntimeFlavor runtimeFlavor;
39+
@TestParameter public boolean isParseOnly;
40+
41+
private Cel cel;
42+
43+
@Before
44+
public void setUp() {
45+
// Legacy runtime does not support parsed-only evaluation mode.
46+
Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
47+
this.cel =
48+
runtimeFlavor
49+
.builder()
50+
.addCompilerLibraries(CelExtensions.regex())
51+
.addRuntimeLibraries(CelExtensions.regex())
52+
.build();
53+
}
54+
4255

4356
@Test
4457
public void library() {
@@ -80,11 +93,7 @@ public void library() {
8093
public void replaceAll_success(String target, String regex, String replaceStr, String res)
8194
throws Exception {
8295
String expr = String.format("regex.replace('%s', '%s', '%s')", target, regex, replaceStr);
83-
CelRuntime.Program program = RUNTIME.createProgram(COMPILER.compile(expr).getAst());
84-
85-
Object result = program.eval();
86-
87-
assertThat(result).isEqualTo(res);
96+
assertThat(eval(expr)).isEqualTo(res);
8897
}
8998

9099
@Test
@@ -93,11 +102,7 @@ public void replace_nested_success() throws Exception {
93102
"regex.replace("
94103
+ " regex.replace('%(foo) %(bar) %2','%\\\\((\\\\w+)\\\\)','${\\\\1}'),"
95104
+ " '%(\\\\d+)', '$\\\\1')";
96-
CelRuntime.Program program = RUNTIME.createProgram(COMPILER.compile(expr).getAst());
97-
98-
Object result = program.eval();
99-
100-
assertThat(result).isEqualTo("${foo} ${bar} $2");
105+
assertThat(eval(expr)).isEqualTo("${foo} ${bar} $2");
101106
}
102107

103108
@Test
@@ -118,11 +123,7 @@ public void replace_nested_success() throws Exception {
118123
public void replaceCount_success(String t, String re, String rep, long i, String res)
119124
throws Exception {
120125
String expr = String.format("regex.replace('%s', '%s', '%s', %d)", t, re, rep, i);
121-
CelRuntime.Program program = RUNTIME.createProgram(COMPILER.compile(expr).getAst());
122-
123-
Object result = program.eval();
124-
125-
assertThat(result).isEqualTo(res);
126+
assertThat(eval(expr)).isEqualTo(res);
126127
}
127128

128129
@Test
@@ -131,10 +132,8 @@ public void replaceCount_success(String t, String re, String rep, long i, String
131132
public void replace_invalidRegex_throwsException(String target, String regex, String replaceStr)
132133
throws Exception {
133134
String expr = String.format("regex.replace('%s', '%s', '%s')", target, regex, replaceStr);
134-
CelAbstractSyntaxTree ast = COMPILER.compile(expr).getAst();
135-
136135
CelEvaluationException e =
137-
assertThrows(CelEvaluationException.class, () -> RUNTIME.createProgram(ast).eval());
136+
assertThrows(CelEvaluationException.class, () -> eval(expr));
138137

139138
assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
140139
assertThat(e).hasCauseThat().hasMessageThat().contains("Failed to compile regex: ");
@@ -143,10 +142,8 @@ public void replace_invalidRegex_throwsException(String target, String regex, St
143142
@Test
144143
public void replace_invalidCaptureGroupReplaceStr_throwsException() throws Exception {
145144
String expr = "regex.replace('test', '(.)', '\\\\2')";
146-
CelAbstractSyntaxTree ast = COMPILER.compile(expr).getAst();
147-
148145
CelEvaluationException e =
149-
assertThrows(CelEvaluationException.class, () -> RUNTIME.createProgram(ast).eval());
146+
assertThrows(CelEvaluationException.class, () -> eval(expr));
150147

151148
assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
152149
assertThat(e)
@@ -158,10 +155,8 @@ public void replace_invalidCaptureGroupReplaceStr_throwsException() throws Excep
158155
@Test
159156
public void replace_trailingBackslashReplaceStr_throwsException() throws Exception {
160157
String expr = "regex.replace('id=123', 'id=(?P<value>\\\\d+)', '\\\\')";
161-
CelAbstractSyntaxTree ast = COMPILER.compile(expr).getAst();
162-
163158
CelEvaluationException e =
164-
assertThrows(CelEvaluationException.class, () -> RUNTIME.createProgram(ast).eval());
159+
assertThrows(CelEvaluationException.class, () -> eval(expr));
165160

166161
assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
167162
assertThat(e)
@@ -173,10 +168,8 @@ public void replace_trailingBackslashReplaceStr_throwsException() throws Excepti
173168
@Test
174169
public void replace_invalidGroupReferenceReplaceStr_throwsException() throws Exception {
175170
String expr = "regex.replace('id=123', 'id=(?P<value>\\\\d+)', '\\\\a')";
176-
CelAbstractSyntaxTree ast = COMPILER.compile(expr).getAst();
177-
178171
CelEvaluationException e =
179-
assertThrows(CelEvaluationException.class, () -> RUNTIME.createProgram(ast).eval());
172+
assertThrows(CelEvaluationException.class, () -> eval(expr));
180173

181174
assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
182175
assertThat(e)
@@ -199,9 +192,7 @@ public void replace_invalidGroupReferenceReplaceStr_throwsException() throws Exc
199192
@TestParameters("{target: 'brand', regex: 'brand', expectedResult: 'brand'}")
200193
public void extract_success(String target, String regex, String expectedResult) throws Exception {
201194
String expr = String.format("regex.extract('%s', '%s')", target, regex);
202-
CelRuntime.Program program = RUNTIME.createProgram(COMPILER.compile(expr).getAst());
203-
204-
Object result = program.eval();
195+
Object result = eval(expr);
205196

206197
assertThat(result).isInstanceOf(Optional.class);
207198
assertThat((Optional<?>) result).hasValue(expectedResult);
@@ -213,9 +204,7 @@ public void extract_success(String target, String regex, String expectedResult)
213204
@TestParameters("{target: '', regex: '\\\\w+'}")
214205
public void extract_no_match(String target, String regex) throws Exception {
215206
String expr = String.format("regex.extract('%s', '%s')", target, regex);
216-
CelRuntime.Program program = RUNTIME.createProgram(COMPILER.compile(expr).getAst());
217-
218-
Object result = program.eval();
207+
Object result = eval(expr);
219208

220209
assertThat(result).isInstanceOf(Optional.class);
221210
assertThat((Optional<?>) result).isEmpty();
@@ -227,10 +216,8 @@ public void extract_no_match(String target, String regex) throws Exception {
227216
public void extract_multipleCaptureGroups_throwsException(String target, String regex)
228217
throws Exception {
229218
String expr = String.format("regex.extract('%s', '%s')", target, regex);
230-
CelAbstractSyntaxTree ast = COMPILER.compile(expr).getAst();
231-
232219
CelEvaluationException e =
233-
assertThrows(CelEvaluationException.class, () -> RUNTIME.createProgram(ast).eval());
220+
assertThrows(CelEvaluationException.class, () -> eval(expr));
234221

235222
assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
236223
assertThat(e)
@@ -263,9 +250,7 @@ private enum ExtractAllTestCase {
263250

264251
@Test
265252
public void extractAll_success(@TestParameter ExtractAllTestCase testCase) throws Exception {
266-
CelAbstractSyntaxTree ast = COMPILER.compile(testCase.expr).getAst();
267-
268-
Object result = RUNTIME.createProgram(ast).eval();
253+
Object result = eval(testCase.expr);
269254

270255
assertThat(result).isEqualTo(testCase.expectedResult);
271256
}
@@ -281,15 +266,19 @@ public void extractAll_success(@TestParameter ExtractAllTestCase testCase) throw
281266
public void extractAll_multipleCaptureGroups_throwsException(String target, String regex)
282267
throws Exception {
283268
String expr = String.format("regex.extractAll('%s', '%s')", target, regex);
284-
CelAbstractSyntaxTree ast = COMPILER.compile(expr).getAst();
285-
286269
CelEvaluationException e =
287-
assertThrows(CelEvaluationException.class, () -> RUNTIME.createProgram(ast).eval());
270+
assertThrows(CelEvaluationException.class, () -> eval(expr));
288271

289272
assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
290273
assertThat(e)
291274
.hasCauseThat()
292275
.hasMessageThat()
293276
.contains("Regular expression has more than one capturing group:");
294277
}
278+
279+
private Object eval(String expr) throws Exception {
280+
CelAbstractSyntaxTree ast =
281+
isParseOnly ? cel.parse(expr).getAst() : cel.compile(expr).getAst();
282+
return cel.createProgram(ast).eval();
283+
}
295284
}

optimizer/src/test/java/dev/cel/optimizer/optimizers/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ java_library(
1111
deps = [
1212
# "//java/com/google/testing/testsize:annotations",
1313
"//bundle:cel",
14-
"//bundle:cel_experimental_factory",
1514
"//common:cel_ast",
1615
"//common:cel_source",
1716
"//common:compiler_common",
@@ -37,6 +36,7 @@ java_library(
3736
"//runtime:program",
3837
"//runtime:unknown_attributes",
3938
"//testing:baseline_test_case",
39+
"//testing:cel_runtime_flavor",
4040
"@maven//:junit_junit",
4141
"@maven//:com_google_testparameterinjector_test_parameter_injector",
4242
"//:java_truth",

0 commit comments

Comments
 (0)