| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #include <jvalidate/extension.h>
- #include <gmock/gmock.h>
- #include <gtest/gtest.h>
- #include <json/value.h>
- #include <jvalidate/adapters/jsoncpp.h>
- #include <jvalidate/constraint/extension_constraint.h>
- #include <jvalidate/detail/expect.h>
- #include <jvalidate/detail/relative_pointer.h>
- #include <jvalidate/forward.h>
- #include <jvalidate/status.h>
- #include <jvalidate/validator.h>
- #include "matchers.h"
- using enum jvalidate::schema::Version;
- using jvalidate::Status;
- using jvalidate::constraint::ExtensionConstraint;
- using testing::Not;
- struct IsKeyOfConstraint : jvalidate::extension::ConstraintBase<IsKeyOfConstraint> {
- IsKeyOfConstraint(std::string_view ptr) : ptr(ptr) {
- EXPECT_M(ptr.find('/') != std::string_view::npos,
- "IsKeyOfConstraint requires a value-relative-pointer, not a key-relative-pointer");
- }
- jvalidate::detail::RelativePointer ptr;
- };
- template <jvalidate::Adapter A>
- class Visitor : public jvalidate::extension::Visitor<Visitor<A>, IsKeyOfConstraint> {
- public:
- Visitor(A const & root_document) : root_document_(root_document) {}
- template <jvalidate::Adapter A2>
- Status visit(IsKeyOfConstraint const & cons, A2 const & document, auto const & validator) const {
- validator.annotate(cons.ptr);
- auto const & object =
- std::get<1>(cons.ptr.inspect(validator.where_, root_document_)).as_object();
- if (object.find(document.as_string()) != object.end()) {
- return Status::Accept;
- }
- return Status::Reject;
- }
- private:
- A root_document_;
- };
- auto validate(Json::Value const & schema_doc, Json::Value const & instance_doc,
- jvalidate::schema::Version version = Draft2020_12) {
- using A = jvalidate::adapter::AdapterFor<Json::Value const>;
- jvalidate::ConstraintFactory<A> factory{{"is_key_of", [](auto const & context) {
- return ExtensionConstraint::make<IsKeyOfConstraint>(
- context.schema.as_string());
- }}};
- jvalidate::Schema const schema(schema_doc, version, factory);
- jvalidate::ValidationResult result;
- (void)jvalidate::Validator(schema, Visitor(A(instance_doc))).validate(instance_doc, &result);
- return result;
- }
- TEST(ExtensionConstraint, CanReportSuccess) {
- auto schema = R"({
- "properties": {
- "nodes": {
- "type": "object"
- },
- "edges": {
- "items": {
- "properties": {
- "destination": {
- "is_key_of": "3/nodes",
- "type": "string"
- },
- "source": {
- "is_key_of": "3/nodes",
- "type": "string"
- }
- },
- "type": "object"
- },
- "type": "array"
- }
- },
- "type": "object"
- })"_json;
- auto instance = R"({
- "nodes": {
- "A": {},
- "B": {}
- },
- "edges": [
- { "source": "A", "destination": "B" }
- ]
- })"_json;
- jvalidate::ValidationResult result = validate(schema, instance);
- EXPECT_THAT(result, Valid());
- }
- TEST(ExtensionConstraint, CanReportFailure) {
- auto schema = R"({
- "properties": {
- "nodes": {
- "type": "object"
- },
- "edges": {
- "items": {
- "properties": {
- "destination": {
- "is_key_of": "3/nodes",
- "type": "string"
- },
- "source": {
- "is_key_of": "3/nodes",
- "type": "string"
- }
- },
- "type": "object"
- },
- "type": "array"
- }
- },
- "type": "object"
- })"_json;
- auto instance = R"({
- "nodes": {
- "A": {},
- "B": {}
- },
- "edges": [
- { "source": "A", "destination": "C" }
- ]
- })"_json;
- jvalidate::ValidationResult result = validate(schema, instance);
- EXPECT_THAT(result, Not(Valid()));
- }
- int main(int argc, char ** argv) {
- testing::InitGoogleMock(&argc, argv);
- return RUN_ALL_TESTS();
- }
|