mirror of
https://github.com/tristanpenman/valijson.git
synced 2025-03-03 12:58:03 +01:00
Initial support for 'if', 'then' and 'else' subschemas
This commit is contained in:
parent
dac4cff42f
commit
925ff8ff68
@ -118,7 +118,51 @@ private:
|
|||||||
class ConditionalConstraint: public BasicConstraint<ConditionalConstraint>
|
class ConditionalConstraint: public BasicConstraint<ConditionalConstraint>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConditionalConstraint() { }
|
ConditionalConstraint()
|
||||||
|
: ifSubschema(NULL),
|
||||||
|
thenSubschema(NULL),
|
||||||
|
elseSubschema(NULL) { }
|
||||||
|
|
||||||
|
ConditionalConstraint(CustomAlloc allocFn, CustomFree freeFn)
|
||||||
|
: BasicConstraint(allocFn, freeFn),
|
||||||
|
ifSubschema(NULL),
|
||||||
|
thenSubschema(NULL),
|
||||||
|
elseSubschema(NULL) { }
|
||||||
|
|
||||||
|
const Subschema * getIfSubschema() const
|
||||||
|
{
|
||||||
|
return ifSubschema;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Subschema * getThenSubschema() const
|
||||||
|
{
|
||||||
|
return thenSubschema;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Subschema * getElseSubschema() const
|
||||||
|
{
|
||||||
|
return elseSubschema;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIfSubschema(const Subschema *subschema)
|
||||||
|
{
|
||||||
|
ifSubschema = subschema;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setThenSubschema(const Subschema *subschema)
|
||||||
|
{
|
||||||
|
thenSubschema = subschema;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setElseSubschema(const Subschema *subschema)
|
||||||
|
{
|
||||||
|
elseSubschema = subschema;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Subschema *ifSubschema;
|
||||||
|
const Subschema *thenSubschema;
|
||||||
|
const Subschema *elseSubschema;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,7 +37,8 @@ public:
|
|||||||
/// Supported versions of JSON Schema
|
/// Supported versions of JSON Schema
|
||||||
enum Version {
|
enum Version {
|
||||||
kDraft3, ///< @deprecated JSON Schema v3 has been superseded by v4
|
kDraft3, ///< @deprecated JSON Schema v3 has been superseded by v4
|
||||||
kDraft4
|
kDraft4,
|
||||||
|
kDraft7
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Version of JSON Schema that should be expected when parsing
|
/// Version of JSON Schema that should be expected when parsing
|
||||||
@ -710,6 +711,25 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const typename AdapterType::Object::const_iterator ifItr = object.find("if");
|
||||||
|
const typename AdapterType::Object::const_iterator thenItr = object.find("then");
|
||||||
|
const typename AdapterType::Object::const_iterator elseItr = object.find("end");
|
||||||
|
|
||||||
|
if (object.end() != ifItr && object.end() != thenItr) {
|
||||||
|
if (version == kDraft7) {
|
||||||
|
rootSchema.addConstraintToSubschema(
|
||||||
|
makeConditionalConstraint(rootSchema, rootNode,
|
||||||
|
ifItr->second, thenItr->second,
|
||||||
|
elseItr == object.end() ? NULL : &elseItr->second,
|
||||||
|
updatedScope, nodePath, fetchDoc, docCache, schemaCache),
|
||||||
|
&subschema);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((itr = object.find("maximum")) != object.end()) {
|
if ((itr = object.find("maximum")) != object.end()) {
|
||||||
typename AdapterType::Object::const_iterator exclusiveMaximumItr =
|
typename AdapterType::Object::const_iterator exclusiveMaximumItr =
|
||||||
object.find("exclusiveMaximum");
|
object.find("exclusiveMaximum");
|
||||||
@ -1138,6 +1158,24 @@ private:
|
|||||||
{
|
{
|
||||||
constraints::ConditionalConstraint constraint;
|
constraints::ConditionalConstraint constraint;
|
||||||
|
|
||||||
|
const Subschema *ifSubschema = makeOrReuseSchema<AdapterType>(
|
||||||
|
rootSchema, rootNode, ifNode, currentScope,
|
||||||
|
nodePath, fetchDoc, NULL, NULL, docCache,
|
||||||
|
schemaCache);
|
||||||
|
constraint.setIfSubschema(ifSubschema);
|
||||||
|
|
||||||
|
const Subschema *thenSubschema = makeOrReuseSchema<AdapterType>(
|
||||||
|
rootSchema, rootNode, thenNode, currentScope, nodePath, fetchDoc, NULL, NULL,
|
||||||
|
docCache, schemaCache);
|
||||||
|
constraint.setThenSubschema(thenSubschema);
|
||||||
|
|
||||||
|
if (elseNode) {
|
||||||
|
const Subschema *elseSubschema = makeOrReuseSchema<AdapterType>(
|
||||||
|
rootSchema, rootNode, *elseNode, currentScope, nodePath, fetchDoc, NULL, NULL,
|
||||||
|
docCache, schemaCache);
|
||||||
|
constraint.setElseSubschema(elseSubschema);
|
||||||
|
}
|
||||||
|
|
||||||
return constraint;
|
return constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,11 +158,30 @@ public:
|
|||||||
return numValidated > 0;
|
return numValidated > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate current node using a set of 'if', 'then' and 'else' subschemas
|
||||||
|
*
|
||||||
|
* A conditional constraint allows a document to validated against one of two additional
|
||||||
|
* subschemas (specified via 'then' or 'else' properties) depending on whether the document
|
||||||
|
* satifies an optional subschema (specified via the 'if' property).
|
||||||
|
*
|
||||||
|
* @param constraint ConditionalConstraint that the current node must validate against
|
||||||
|
*
|
||||||
|
* @return \c true if validation passes; \c false otherwise
|
||||||
|
*/
|
||||||
virtual bool visit(const ConditionalConstraint &constraint)
|
virtual bool visit(const ConditionalConstraint &constraint)
|
||||||
{
|
{
|
||||||
return false;
|
// Create a validator to evaluate the conditional
|
||||||
|
ValidationVisitor ifValidator(target, context, strictTypes, NULL);
|
||||||
|
ValidationVisitor thenElseValidator(target, context, strictTypes, NULL);
|
||||||
|
|
||||||
|
if (ifValidator.validateSchema(*constraint.getIfSubschema())) {
|
||||||
|
return thenElseValidator.validateSchema(*constraint.getThenSubschema());
|
||||||
|
} else {
|
||||||
|
return thenElseValidator.validateSchema(*constraint.getElseSubschema());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Validate current node against a 'dependencies' constraint
|
* @brief Validate current node against a 'dependencies' constraint
|
||||||
*
|
*
|
||||||
|
@ -183,6 +183,11 @@ protected:
|
|||||||
{
|
{
|
||||||
return processTestFile(testFile, SchemaParser::kDraft4);
|
return processTestFile(testFile, SchemaParser::kDraft4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void processDraft7TestFile(const std::string &testFile)
|
||||||
|
{
|
||||||
|
return processTestFile(testFile, SchemaParser::kDraft7);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(TestValidator, Draft3_AdditionalItems)
|
TEST_F(TestValidator, Draft3_AdditionalItems)
|
||||||
@ -414,3 +419,8 @@ TEST_F(TestValidator, Draft4_UniqueItems)
|
|||||||
{
|
{
|
||||||
processDraft4TestFile(TEST_SUITE_DIR "draft4/uniqueItems.json");
|
processDraft4TestFile(TEST_SUITE_DIR "draft4/uniqueItems.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TestValidator, Draft7_IfThenElse)
|
||||||
|
{
|
||||||
|
processDraft7TestFile(TEST_SUITE_DIR "draft7/if-then-else.json");
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user