Browse Source

improved json validation by getting a list of invalid removed parts when getValidParts is used

Kolja Strohm 1 year ago
parent
commit
1e174f051d
4 changed files with 141 additions and 35 deletions
  1. BIN
      Framework Tests/Framwork.dll
  2. 28 5
      Framework Tests/Json.cpp
  3. 83 18
      JSON.cpp
  4. 30 12
      JSON.h

BIN
Framework Tests/Framwork.dll


+ 28 - 5
Framework Tests/Json.cpp

@@ -597,7 +597,16 @@ namespace FrameworkTests
             result->printInvalidInfo();
             Assert::IsTrue(
                 !result->isValid(), L"Invalid Json was marked as valid");
-            Framework::JSON::JSONValue* validValue = result->getValidPart();
+            Framework::RCArray<Framework::JSON::Validator::JSONValidationResult>
+                invalidParts;
+            Framework::JSON::JSONValue* validValue
+                = result->getValidPart(&invalidParts);
+            Assert::IsTrue(invalidParts.getEintragAnzahl() > 0, L"No Invalid parts were returned for an invalid Json");
+            for (Framework::JSON::Validator::JSONValidationResult* invalid :
+                invalidParts)
+            {
+                invalid->printInvalidInfo();
+            }
             result->release();
             Assert::IsTrue(validValue == 0,
                 L"getValidPart of invalid validation result without "
@@ -699,7 +708,7 @@ namespace FrameworkTests
             result->printInvalidInfo();
             Assert::IsTrue(
                 !result->isValid(), L"Invalid Json was marked as valid");
-            Framework::JSON::JSONValue* validValue = result->getValidPart();
+            Framework::JSON::JSONValue* validValue = result->getValidPart(0);
             result->release();
             Framework::JSON::JSONValue* expected
                 = Framework::JSON::Parser::getValue(
@@ -718,7 +727,11 @@ namespace FrameworkTests
                 L"validation result should never return an invalid validation "
                 L"result");
             value->release();
-            value = result->getValidPart();
+            Framework::RCArray<Framework::JSON::Validator::JSONValidationResult>
+                invalidParts;
+            value = result->getValidPart(&invalidParts);
+            Assert::IsTrue(invalidParts.getEintragAnzahl() == 0,
+                L"Invalid parts were returned for a valid validation result");
             Assert::IsTrue(JSONParserTests::isEqual(validValue, value),
                 L"getValidPart of a valid validation result should return the "
                 L"validated value");
@@ -856,7 +869,17 @@ namespace FrameworkTests
             result->printInvalidInfo();
             Assert::IsTrue(
                 !result->isValid(), L"Invalid Json was marked as valid");
-            Framework::JSON::JSONValue* validValue = result->getValidPart();
+            Framework::RCArray<Framework::JSON::Validator::JSONValidationResult>
+                invalidParts;
+            Framework::JSON::JSONValue* validValue
+                = result->getValidPart(&invalidParts);
+            Assert::IsTrue(invalidParts.getEintragAnzahl() > 0,
+                L"No Invalid parts were returned for an invalid Json");
+            for (Framework::JSON::Validator::JSONValidationResult* invalid :
+                invalidParts)
+            {
+                invalid->printInvalidInfo();
+            }
             result->release();
             Framework::JSON::JSONValue* expected
                 = Framework::JSON::Parser::getValue(
@@ -879,7 +902,7 @@ namespace FrameworkTests
                 L"validation result should never return an invalid validation "
                 L"result");
             value->release();
-            value = result->getValidPart();
+            value = result->getValidPart(0);
             Assert::IsTrue(JSONParserTests::isEqual(validValue, value),
                 L"getValidPart of a valid validation result should return the "
                 L"validated value");

+ 83 - 18
JSON.cpp

@@ -687,11 +687,13 @@ void JSONTypeMissmatch::printInvalidInfo(int indent) const
     }
 }
 
-JSONValue* JSONTypeMissmatch::getValidPart() const
+JSONValue* JSONTypeMissmatch::getValidPart(
+    RCArray<JSONValidationResult>* removedPartsValidationResults)
 {
     if (reason)
     {
-        JSONValue* valid = reason->getValidPart();
+        RCArray<JSONValidationResult> temporaryInvalidParts;
+        JSONValue* valid = reason->getValidPart(&temporaryInvalidParts);
         Text* p = reason->getPath().getTeilText(path.getLength());
         if (foundValue->getType() == JSONType::ARRAY)
         {
@@ -700,6 +702,11 @@ JSONValue* JSONTypeMissmatch::getValidPart() const
                     || !expected->getAttributeValue("removeInvalidEntries")
                             .istGleich("true")))
             {
+                if (removedPartsValidationResults)
+                {
+                    removedPartsValidationResults->add(
+                        dynamic_cast<JSONValidationResult*>(getThis()));
+                }
                 p->release();
                 return 0;
             }
@@ -710,6 +717,15 @@ JSONValue* JSONTypeMissmatch::getValidPart() const
                 it->release();
                 if (i >= 0 && foundValue->asArray()->getLength() > i)
                 {
+                    if (removedPartsValidationResults)
+                    {
+                        for (JSONValidationResult* res : temporaryInvalidParts)
+                        {
+                            removedPartsValidationResults->add(
+                                dynamic_cast<JSONValidationResult*>(
+                                    res->getThis()));
+                        }
+                    }
                     JSONValue* tmp = foundValue->clone();
                     if (valid)
                         tmp->asArray()->setValue(i, valid);
@@ -728,7 +744,8 @@ JSONValue* JSONTypeMissmatch::getValidPart() const
                     {
                         p->release();
                         tmp->release();
-                        JSONValue* result = res->getValidPart();
+                        JSONValue* result
+                            = res->getValidPart(removedPartsValidationResults);
                         res->release();
                         return result;
                     }
@@ -744,11 +761,25 @@ JSONValue* JSONTypeMissmatch::getValidPart() const
                     || !expected->getAttributeValue("removeInvalidEntries")
                             .istGleich("true")))
             {
+                if (removedPartsValidationResults)
+                {
+                    removedPartsValidationResults->add(
+                        dynamic_cast<JSONValidationResult*>(getThis()));
+                }
                 p->release();
                 return 0;
             }
             if (p->hatAt(0, "."))
             {
+                if (removedPartsValidationResults)
+                {
+                    for (JSONValidationResult* res : temporaryInvalidParts)
+                    {
+                        removedPartsValidationResults->add(
+                            dynamic_cast<JSONValidationResult*>(
+                                res->getThis()));
+                    }
+                }
                 Text* at = p->getTeilText(1);
                 Text attr = *at;
                 at->release();
@@ -768,7 +799,8 @@ JSONValue* JSONTypeMissmatch::getValidPart() const
                 {
                     p->release();
                     tmp->release();
-                    JSONValue* result = res->getValidPart();
+                    JSONValue* result
+                        = res->getValidPart(removedPartsValidationResults);
                     res->release();
                     return result;
                 }
@@ -779,6 +811,11 @@ JSONValue* JSONTypeMissmatch::getValidPart() const
         p->release();
         if (valid) valid->release();
     }
+    if (removedPartsValidationResults)
+    {
+        removedPartsValidationResults->add(
+            dynamic_cast<JSONValidationResult*>(getThis()));
+    }
     return 0;
 }
 
@@ -827,8 +864,14 @@ void JSONUnknownValue::printInvalidInfo(int indent) const
               << ind.getText() << foundValue->toString().getText() << "\n";
 }
 
-JSONValue* JSONUnknownValue::getValidPart() const
+JSONValue* JSONUnknownValue::getValidPart(
+    RCArray<JSONValidationResult>* removedPartsValidationResults)
 {
+    if (removedPartsValidationResults)
+    {
+        removedPartsValidationResults->add(
+            dynamic_cast<JSONValidationResult*>(getThis()));
+    }
     return 0;
 }
 
@@ -877,7 +920,8 @@ void JSONMissingValue::printInvalidInfo(int indent) const
               << ind.getText() << expected->toString().getText() << "\n";
 }
 
-JSONValue* JSONMissingValue::getValidPart() const
+JSONValue* JSONMissingValue::getValidPart(
+    RCArray<JSONValidationResult>* removedPartsValidationResults)
 {
     if (expected->hasAttribute("default"))
     {
@@ -894,12 +938,18 @@ JSONValue* JSONMissingValue::getValidPart() const
         else if (res->isDifferent(this, path))
         {
             def->release();
-            JSONValue* result = res->getValidPart();
+            JSONValue* result
+                = res->getValidPart(removedPartsValidationResults);
             res->release();
             return result;
         }
         def->release();
     }
+    if (removedPartsValidationResults)
+    {
+        removedPartsValidationResults->add(
+            dynamic_cast<JSONValidationResult*>(getThis()));
+    }
     return 0;
 }
 
@@ -950,8 +1000,14 @@ void JSONMissingOneOf::printInvalidInfo(int indent) const
     }
 }
 
-JSONValue* JSONMissingOneOf::getValidPart() const
+JSONValue* JSONMissingOneOf::getValidPart(
+    RCArray<JSONValidationResult>* removedPartsValidationResults)
 {
+    if (removedPartsValidationResults)
+    {
+        removedPartsValidationResults->add(
+            dynamic_cast<JSONValidationResult*>(getThis()));
+    }
     // multiple possibilities are undecidable
     return 0;
 }
@@ -1016,8 +1072,14 @@ void JSONNoTypeMatching::printInvalidInfo(int indent) const
     }
 }
 
-JSONValue* JSONNoTypeMatching::getValidPart() const
+JSONValue* JSONNoTypeMatching::getValidPart(
+    RCArray<JSONValidationResult>* removedPartsValidationResults)
 {
+    if (removedPartsValidationResults)
+    {
+        removedPartsValidationResults->add(
+            dynamic_cast<JSONValidationResult*>(getThis()));
+    }
     // multiple possibilities are undecidable
     return 0;
 }
@@ -1065,7 +1127,8 @@ bool JSONValidValue::isValid() const
 
 void JSONValidValue::printInvalidInfo(int indent) const {}
 
-JSONValue* JSONValidValue::getValidPart() const
+JSONValue* JSONValidValue::getValidPart(
+    RCArray<JSONValidationResult>* removedPartsValidationResults)
 {
     return value->clone();
 }
@@ -1117,7 +1180,8 @@ bool JSONValidator::isValid(JSONValue* zValue) const
     return 0;
 }
 
-JSONValue* JSONValidator::getValidParts(JSONValue* zValue) const
+JSONValue* JSONValidator::getValidParts(JSONValue* zValue,
+    RCArray<JSONValidationResult>* removedPartsValidationResults) const
 {
     JSONValidationResult* res = validate(zValue);
     if (res->isValid())
@@ -1125,7 +1189,7 @@ JSONValue* JSONValidator::getValidParts(JSONValue* zValue) const
         res->release();
         return zValue->clone();
     }
-    JSONValue* valid = res->getValidPart();
+    JSONValue* valid = res->getValidPart(removedPartsValidationResults);
     res->release();
     return valid;
 }
@@ -1340,9 +1404,9 @@ JSONValidationResult* JSONValidator::validate(
         {
             Text id = zConstraints->getAttributeValue("ref");
             XML::Editor editor = constraints->select()
-                .selectAllElements()
-                .whereNameEquals("object")
-                .whereAttributeEquals("id", id);
+                                     .selectAllElements()
+                                     .whereNameEquals("object")
+                                     .whereAttributeEquals("id", id);
             if (editor.getSize())
             {
                 zConstraints = editor.begin().val();
@@ -1398,11 +1462,11 @@ JSONValidationResult* JSONValidator::validate(
                 {
                     XML::Editor tmp = constraint->selectChildren();
                     bool optional = true;
-                    tmp.forEach([&optional](XML::Element* zElement) { 
+                    tmp.forEach([&optional](XML::Element* zElement) {
                         optional &= zElement->hasAttribute("optional")
                                  && zElement->getAttributeValue("optional")
                                         .istGleich("true");
-                        });
+                    });
                     if (!optional)
                     {
                         Text p = path;
@@ -1416,7 +1480,8 @@ JSONValidationResult* JSONValidator::validate(
                                 new JSONMissingOneOf(p, tmp));
                         return new JSONTypeMissmatch(path,
                             dynamic_cast<JSONValue*>(zValue->getThis()),
-                            dynamic_cast<XML::Element*>(zConstraints->getThis()),
+                            dynamic_cast<XML::Element*>(
+                                zConstraints->getThis()),
                             new JSONMissingValue(p,
                                 dynamic_cast<XML::Element*>(
                                     tmp.begin()->getThis())));

+ 30 - 12
JSON.h

@@ -249,10 +249,13 @@ namespace Framework
                 __declspec(dllexport) virtual ~JSONValidationResult();
                 virtual bool isValid() const = 0;
                 virtual void printInvalidInfo(int indent = 0) const = 0;
-                virtual JSONValue* getValidPart() const = 0;
+                virtual JSONValue* getValidPart(RCArray<JSONValidationResult>*
+                        zRemovedPartsValidationResults)
+                    = 0;
                 virtual Text getPath() const = 0;
                 virtual bool isDifferent(const JSONValidationResult* zResult,
-                    Text additionalPath) const = 0;
+                    Text additionalPath) const
+                    = 0;
             };
 
             class JSONTypeMissmatch : public JSONValidationResult
@@ -272,7 +275,9 @@ namespace Framework
                 __declspec(dllexport) bool isValid() const override;
                 __declspec(dllexport) void printInvalidInfo(
                     int indent) const override;
-                __declspec(dllexport) JSONValue* getValidPart() const override;
+                __declspec(dllexport) JSONValue* getValidPart(
+                    RCArray<JSONValidationResult>*
+                        zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 bool isDifferent(const JSONValidationResult* zResult,
                     Text additionalPath) const override;
@@ -291,7 +296,9 @@ namespace Framework
                 __declspec(dllexport) bool isValid() const override;
                 __declspec(dllexport) void printInvalidInfo(
                     int indent) const override;
-                __declspec(dllexport) JSONValue* getValidPart() const override;
+                __declspec(dllexport) JSONValue* getValidPart(
+                    RCArray<JSONValidationResult>*
+                        zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
                     const JSONValidationResult* zResult,
@@ -311,7 +318,9 @@ namespace Framework
                 __declspec(dllexport) bool isValid() const override;
                 __declspec(dllexport) void printInvalidInfo(
                     int indent) const override;
-                __declspec(dllexport) JSONValue* getValidPart() const override;
+                __declspec(dllexport) JSONValue* getValidPart(
+                    RCArray<JSONValidationResult>*
+                        zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
                     const JSONValidationResult* zResult,
@@ -331,7 +340,9 @@ namespace Framework
                 __declspec(dllexport) bool isValid() const override;
                 __declspec(dllexport) void printInvalidInfo(
                     int indent) const override;
-                __declspec(dllexport) JSONValue* getValidPart() const override;
+                __declspec(dllexport) JSONValue* getValidPart(
+                    RCArray<JSONValidationResult>*
+                        zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
                     const JSONValidationResult* zResult,
@@ -355,7 +366,9 @@ namespace Framework
                 __declspec(dllexport) bool isValid() const override;
                 __declspec(dllexport) void printInvalidInfo(
                     int indent) const override;
-                __declspec(dllexport) JSONValue* getValidPart() const override;
+                __declspec(dllexport) JSONValue* getValidPart(
+                    RCArray<JSONValidationResult>*
+                        zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
                     const JSONValidationResult* zResult,
@@ -375,7 +388,9 @@ namespace Framework
                 __declspec(dllexport) bool isValid() const override;
                 __declspec(dllexport) void printInvalidInfo(
                     int indent) const override;
-                __declspec(dllexport) JSONValue* getValidPart() const override;
+                __declspec(dllexport) JSONValue* getValidPart(
+                    RCArray<JSONValidationResult>*
+                        zRemovedPartsValidationResults) override;
                 __declspec(dllexport) Text getPath() const override;
                 __declspec(dllexport) bool isDifferent(
                     const JSONValidationResult* zResult,
@@ -417,7 +432,9 @@ namespace Framework
                  * @return the valid part or 0 if no valid part exists
                  */
                 __declspec(dllexport) JSONValue* getValidParts(
-                    JSONValue* zValue) const;
+                    JSONValue* zValue,
+                    RCArray<JSONValidationResult>*
+                        zRemovedPartsValidationResults) const;
                 __declspec(dllexport) XML::Element* zConstraints();
 
             private:
@@ -442,7 +459,9 @@ namespace Framework
                     JSONValidator>* buildForObject();
                 __declspec(dllexport) static ArrayValidationBuilder<
                     JSONValidator>* buildForArray();
-                __declspec(dllexport) static JSONValidator* buildForObjectReference(Text objectId);
+                __declspec(
+                    dllexport) static JSONValidator* buildForObjectReference(Text
+                        objectId);
             };
 
             template<typename T> class StringValidationBuilder
@@ -666,8 +685,7 @@ namespace Framework
                       builder(builder)
                 {}
 
-                ObjectValidationBuilder<T>* setObjectReferenceId(
-                    Text id)
+                ObjectValidationBuilder<T>* setObjectReferenceId(Text id)
                 {
                     element.setAttribute("id", id);
                     return this;