extension_test.cxx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include <jvalidate/constraint/extension_constraint.h>
  2. #include <jvalidate/detail/expect.h>
  3. #include <jvalidate/extension.h>
  4. #include <gmock/gmock.h>
  5. #include <gtest/gtest.h>
  6. #include <json/reader.h>
  7. #include <json/value.h>
  8. #include <jvalidate/adapters/jsoncpp.h>
  9. #include <jvalidate/detail/relative_pointer.h>
  10. #include <jvalidate/status.h>
  11. #include <jvalidate/validator.h>
  12. using jvalidate::Status;
  13. using testing::Eq;
  14. Json::Value operator""_json(char const * data, size_t len) {
  15. Json::Value value;
  16. Json::CharReaderBuilder builder;
  17. std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
  18. std::string error;
  19. if (not reader->parse(data, data + len, &value, &error)) {
  20. throw std::runtime_error(error);
  21. }
  22. return value;
  23. }
  24. struct IsKeyOfConstraint : jvalidate::extension::ConstraintBase<IsKeyOfConstraint> {
  25. IsKeyOfConstraint(std::string_view ptr) : ptr(ptr) {
  26. EXPECT_M(ptr.find('/') != std::string_view::npos,
  27. "IsKeyOfConstraint requires a value-relative-pointer, not a key-relative-pointer");
  28. }
  29. jvalidate::detail::RelativePointer ptr;
  30. };
  31. template <jvalidate::Adapter A>
  32. class Visitor : public jvalidate::extension::Visitor<Visitor<A>, IsKeyOfConstraint> {
  33. public:
  34. Visitor(A const & root_document) : root_document_(root_document) {}
  35. template <jvalidate::Adapter A2>
  36. Status visit(IsKeyOfConstraint const & cons, A2 const & document, auto const & validator) const {
  37. auto const & object =
  38. std::get<1>(cons.ptr.inspect(validator.where_, root_document_)).as_object();
  39. if (object.find(document.as_string()) != object.end()) {
  40. return Status::Accept;
  41. }
  42. return Status::Reject;
  43. }
  44. private:
  45. A const & root_document_;
  46. };
  47. TEST(ExtensionConstraint, CanExtend) {
  48. jvalidate::schema::Node schema;
  49. jvalidate::detail::StdRegexEngine re;
  50. auto json = R"({
  51. "nodes": {
  52. "A": {},
  53. "B": {}
  54. },
  55. "edges": [
  56. { "source": "A", "destination": "B" }
  57. ]
  58. })"_json;
  59. using Adapter = jvalidate::adapter::JsonCppAdapter<Json::Value>;
  60. Adapter document = json;
  61. jvalidate::ValidationVisitor validator(schema, {}, re, Visitor(document), nullptr);
  62. jvalidate::constraint::ExtensionConstraint cons{std::make_unique<IsKeyOfConstraint>("1/nodes")};
  63. EXPECT_THAT(validator.visit(cons, Adapter(json["edges"][0]["source"])), Eq(Status::Accept));
  64. EXPECT_THAT(validator.visit(cons, Adapter(json["edges"][0]["destination"])), Eq(Status::Accept));
  65. }
  66. int main(int argc, char ** argv) {
  67. testing::InitGoogleMock(&argc, argv);
  68. return RUN_ALL_TESTS();
  69. }