1010#include " policy/test_util.h"
1111
1212#include < cstdint>
13+ #include < exception>
1314#include < string>
1415#include < utility>
15- #include < vector>
1616
1717#include " cel/expr/eval.pb.h"
1818#include " cel/expr/value.pb.h"
@@ -131,6 +131,73 @@ absl::Status ParseTestOutput(const YAML::Node& node,
131131 return YamlToExprValue (node, output->mutable_result_value ());
132132}
133133
134+ absl::Status ParseTestCaseNode (
135+ const YAML ::Node& test_node,
136+ cel::expr::conformance::test::TestCase* test_case) {
137+ if (test_node.IsNull ()) {
138+ return absl::OkStatus ();
139+ }
140+ if (!test_node.IsMap ()) {
141+ return absl::InvalidArgumentError (" Test case must be a YAML mapping" );
142+ }
143+ if (test_node[" name" ].IsDefined ()) {
144+ test_case->set_name (test_node[" name" ].as <std::string>());
145+ }
146+ if (test_node[" description" ].IsDefined ()) {
147+ test_case->set_description (test_node[" description" ].as <std::string>());
148+ }
149+ if (test_node[" expr" ].IsDefined ()) {
150+ test_case->set_expr (test_node[" expr" ].as <std::string>());
151+ }
152+ if (test_node[" context_expr" ].IsDefined ()) {
153+ test_case->mutable_input_context ()->set_context_expr (
154+ test_node[" context_expr" ].as <std::string>());
155+ } else if (test_node[" input_context" ].IsDefined () &&
156+ test_node[" input_context" ].IsMap () &&
157+ test_node[" input_context" ][" context_expr" ].IsDefined ()) {
158+ test_case->mutable_input_context ()->set_context_expr (
159+ test_node[" input_context" ][" context_expr" ].as <std::string>());
160+ }
161+ if (test_node[" disable_check" ].IsDefined ()) {
162+ test_case->set_disable_check (test_node[" disable_check" ].as <bool >());
163+ }
164+
165+ YAML ::Node input_node = test_node[" input" ];
166+ if (input_node.IsDefined () && input_node.IsMap ()) {
167+ auto * input_map = test_case->mutable_input ();
168+ for (auto it = input_node.begin (); it != input_node.end (); ++it) {
169+ std::string var_name = it->first .as <std::string>();
170+ cel::expr::conformance::test::InputValue input_val;
171+ CEL_RETURN_IF_ERROR (ParseInputValue (it->second , &input_val));
172+ (*input_map)[var_name] = std::move (input_val);
173+ }
174+ }
175+
176+ YAML ::Node output_node = test_node[" output" ];
177+ if (output_node.IsDefined ()) {
178+ CEL_RETURN_IF_ERROR (
179+ ParseTestOutput (output_node, test_case->mutable_output ()));
180+ }
181+ return absl::OkStatus ();
182+ }
183+
184+ absl::StatusOr<cel::expr::conformance::test::TestCase> ParseTestCaseYamlImpl (
185+ absl::string_view yaml_content) {
186+ if (yaml_content.empty ()) {
187+ return cel::expr::conformance::test::TestCase ();
188+ }
189+ YAML ::Node test_node;
190+ try {
191+ test_node = YAML::Load (std::string (yaml_content));
192+ } catch (const std::exception& e) {
193+ return absl::InvalidArgumentError (
194+ absl::StrCat (" Failed to parse YAML: " , e.what ()));
195+ }
196+ cel::expr::conformance::test::TestCase test_case;
197+ CEL_RETURN_IF_ERROR (ParseTestCaseNode (test_node, &test_case));
198+ return test_case;
199+ }
200+
134201absl::StatusOr<cel::expr::conformance::test::TestSuite>
135202ParsePolicyTestSuiteYamlImpl (absl::string_view yaml_content) {
136203 YAML ::Node tests_node;
@@ -174,33 +241,7 @@ ParsePolicyTestSuiteYamlImpl(absl::string_view yaml_content) {
174241
175242 for (const auto & test_node : tests) {
176243 auto * test_case = section->add_tests ();
177- if (test_node[" name" ].IsDefined ()) {
178- test_case->set_name (test_node[" name" ].as <std::string>());
179- }
180- if (test_node[" description" ].IsDefined ()) {
181- test_case->set_description (test_node[" description" ].as <std::string>());
182- }
183- if (test_node[" context_expr" ].IsDefined ()) {
184- test_case->mutable_input_context ()->set_context_expr (
185- test_node[" context_expr" ].as <std::string>());
186- }
187-
188- YAML ::Node input_node = test_node[" input" ];
189- if (input_node.IsDefined () && input_node.IsMap ()) {
190- auto * input_map = test_case->mutable_input ();
191- for (auto it = input_node.begin (); it != input_node.end (); ++it) {
192- std::string var_name = it->first .as <std::string>();
193- cel::expr::conformance::test::InputValue input_val;
194- CEL_RETURN_IF_ERROR (ParseInputValue (it->second , &input_val));
195- (*input_map)[var_name] = std::move (input_val);
196- }
197- }
198-
199- YAML ::Node output_node = test_node[" output" ];
200- if (output_node.IsDefined ()) {
201- CEL_RETURN_IF_ERROR (
202- ParseTestOutput (output_node, test_case->mutable_output ()));
203- }
244+ CEL_RETURN_IF_ERROR (ParseTestCaseNode (test_node, test_case));
204245 }
205246 }
206247
@@ -218,4 +259,16 @@ ParsePolicyTestSuiteYaml(absl::string_view yaml_content) {
218259 }
219260}
220261
262+ absl::StatusOr<cel::expr::conformance::test::TestCase> ParseTestCaseYaml (
263+ absl::string_view yaml_content) {
264+ try {
265+ return ParseTestCaseYamlImpl (yaml_content);
266+ } catch (const std::exception& e) {
267+ return absl::InvalidArgumentError (
268+ absl::StrCat (" Failed to parse YAML: " , e.what ()));
269+ } catch (...) {
270+ return absl::InvalidArgumentError (" Failed to parse YAML" );
271+ }
272+ }
273+
221274} // namespace cel::test
0 commit comments