Add support for const constraint

This commit is contained in:
Tristan Penman 2019-09-24 20:38:45 +10:00
parent caff3cdbd9
commit 98d804a367
5 changed files with 81 additions and 8 deletions

View File

@ -172,6 +172,34 @@ private:
const Subschema *elseSubschema;
};
class ConstConstraint: public BasicConstraint<ConstConstraint>
{
public:
ConstConstraint()
: value(nullptr) { }
ConstConstraint(CustomAlloc allocFn, CustomFree freeFn)
: BasicConstraint(allocFn, freeFn),
value(nullptr) { }
ConstConstraint(const ConstConstraint &other)
: BasicConstraint(other),
value(other.value->clone()) { }
adapters::FrozenValue * getValue() const
{
return value;
}
void setValue(const adapters::Adapter &value)
{
this->value = value.freeze();
}
private:
adapters::FrozenValue *value;
};
/**
* @brief Represents a 'contains' constraint
*

View File

@ -6,6 +6,7 @@ namespace constraints {
class AllOfConstraint;
class AnyOfConstraint;
class ConditionalConstraint;
class ConstConstraint;
class ContainsConstraint;
class DependenciesConstraint;
class EnumConstraint;
@ -40,6 +41,7 @@ protected:
typedef constraints::AllOfConstraint AllOfConstraint;
typedef constraints::AnyOfConstraint AnyOfConstraint;
typedef constraints::ConditionalConstraint ConditionalConstraint;
typedef constraints::ConstConstraint ConstConstraint;
typedef constraints::ContainsConstraint ContainsConstraint;
typedef constraints::DependenciesConstraint DependenciesConstraint;
typedef constraints::EnumConstraint EnumConstraint;
@ -69,6 +71,7 @@ public:
virtual bool visit(const AllOfConstraint &) = 0;
virtual bool visit(const AnyOfConstraint &) = 0;
virtual bool visit(const ConditionalConstraint &) = 0;
virtual bool visit(const ConstConstraint &) = 0;
virtual bool visit(const ContainsConstraint &) = 0;
virtual bool visit(const DependenciesConstraint &) = 0;
virtual bool visit(const EnumConstraint &) = 0;

View File

@ -649,6 +649,10 @@ private:
&subschema);
}
if ((itr = object.find("const")) != object.end()) {
rootSchema.addConstraintToSubschema(makeConstConstraint(itr->second), &subschema);
}
if ((itr = object.find("contains")) != object.end()) {
rootSchema.addConstraintToSubschema(
makeContainsConstraint(rootSchema, rootNode, itr->second,
@ -1250,6 +1254,21 @@ private:
return constraint;
}
/**
* @brief Make a new ConstConstraint object.
*
* @param node JSON node containing an arbitrary value
*
* @return pointer to a new MinimumConstraint that belongs to the caller
*/
template<typename AdapterType>
constraints::ConstConstraint makeConstConstraint(const AdapterType &node)
{
constraints::ConstConstraint constraint;
constraint.setValue(node);
return constraint;
}
/**
* @brief Make a new ContainsConstraint object.
*

View File

@ -164,7 +164,7 @@ public:
/**
* @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
* A conditional constraint allows a document to be 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).
*
@ -182,11 +182,33 @@ public:
const Subschema *thenSubschema = constraint.getThenSubschema();
return thenSubschema == nullptr ||
thenElseValidator.validateSchema(*thenSubschema);
} else {
}
const Subschema *elseSubschema = constraint.getElseSubschema();
return elseSubschema == nullptr ||
thenElseValidator.validateSchema(*elseSubschema);
}
/**
* @brief Validate current node using a 'const' constraint
*
* A const constraint allows a document to be validated against a specific value.
*
* @param constraint ConstConstraint that the current node must validate against
*
* @return \c true if validation passes; \f false otherwise
*/
virtual bool visit(const ConstConstraint &constraint)
{
if (!constraint.getValue()->equalTo(target, strictTypes)) {
if (results) {
results->pushError(context,
"Failed to match expected value set by 'const' constraint.");
}
return false;
}
return true;
}
/**

View File

@ -451,12 +451,13 @@ TEST_F(TestValidator, Draft7_BooleanSchema)
processDraft7TestFile(TEST_SUITE_DIR "draft7/boolean_schema.json");
}
// TODO: untested const
TEST_F(TestValidator, Draft7_Const)
{
processDraft7TestFile(TEST_SUITE_DIR "draft7/const.json");
}
TEST_F(TestValidator, Draft7_Contains)
{
// TODO: currently failing due to missing support for const
processDraft7TestFile(TEST_SUITE_DIR "draft7/contains.json");
}