json/schema: add additionaProperties tests
This commit is contained in:
parent
8c222300ca
commit
d48e36ffd5
@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
#include "combine.hpp"
|
#include "combine.hpp"
|
||||||
|
|
||||||
|
#include "properties.hpp"
|
||||||
|
|
||||||
#include "../tree.hpp"
|
#include "../tree.hpp"
|
||||||
|
|
||||||
#include "../../iterator.hpp"
|
#include "../../iterator.hpp"
|
||||||
|
#include "../../cast.hpp"
|
||||||
|
|
||||||
using util::json::schema::constraint::combine;
|
using util::json::schema::constraint::combine;
|
||||||
|
|
||||||
@ -38,6 +41,20 @@ combine::combine (::json::tree::node const &def)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_constraints.push_back (instantiate (key, *val));
|
m_constraints.push_back (instantiate (key, *val));
|
||||||
|
|
||||||
|
if (key == "additionalProperties") {
|
||||||
|
m_additional = util::cast::known<additional_properties> (m_constraints.back ().get ());
|
||||||
|
m_additional->use (m_properties);
|
||||||
|
m_additional->use (m_patterns);
|
||||||
|
} else if (key == "properties") {
|
||||||
|
m_properties = util::cast::known<properties> (m_constraints.back().get ());
|
||||||
|
if (m_additional)
|
||||||
|
m_additional->use (m_properties);
|
||||||
|
} else if (key == "patternProperties") {
|
||||||
|
m_patterns = util::cast::known<pattern_properties> (m_constraints.back ().get ());
|
||||||
|
if (m_additional)
|
||||||
|
m_additional->use (m_patterns);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base.hpp"
|
#include "base.hpp"
|
||||||
|
|
||||||
|
#include "fwd.hpp"
|
||||||
#include "../tree.hpp"
|
#include "../tree.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -47,6 +49,10 @@ namespace util::json::schema::constraint {
|
|||||||
std::string m_version;
|
std::string m_version;
|
||||||
std::unique_ptr<::json::tree::node> m_default;
|
std::unique_ptr<::json::tree::node> m_default;
|
||||||
|
|
||||||
|
properties *m_properties = nullptr;
|
||||||
|
pattern_properties *m_patterns = nullptr;
|
||||||
|
additional_properties *m_additional = nullptr;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<base>> m_constraints;
|
std::vector<std::unique_ptr<base>> m_constraints;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -67,6 +67,14 @@ properties::validate (output_iterator res, ::json::tree::node &target) const noe
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
properties::has (std::string const &key) const noexcept
|
||||||
|
{
|
||||||
|
return m_properties.cend () != m_properties.find (key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
std::ostream&
|
std::ostream&
|
||||||
properties::describe (std::ostream &os) const
|
properties::describe (std::ostream &os) const
|
||||||
@ -121,6 +129,20 @@ pattern_properties::validate (output_iterator res,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
pattern_properties::has (std::string const &key) const noexcept
|
||||||
|
{
|
||||||
|
return std::any_of (
|
||||||
|
m_patterns.begin (),
|
||||||
|
m_patterns.end (),
|
||||||
|
[&key] (auto const &i)
|
||||||
|
{
|
||||||
|
return std::regex_search (key, i.matcher);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
std::ostream&
|
std::ostream&
|
||||||
pattern_properties::describe (std::ostream &os) const
|
pattern_properties::describe (std::ostream &os) const
|
||||||
@ -133,11 +155,38 @@ pattern_properties::describe (std::ostream &os) const
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
additional_properties::additional_properties (
|
||||||
|
::json::tree::node const &def,
|
||||||
|
properties *_properties,
|
||||||
|
pattern_properties *_patterns
|
||||||
|
)
|
||||||
|
: m_fallback (def)
|
||||||
|
, m_properties (_properties)
|
||||||
|
, m_patterns (_patterns)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
additional_properties::additional_properties (::json::tree::node const &def):
|
additional_properties::additional_properties (::json::tree::node const &def):
|
||||||
m_fallback (def)
|
additional_properties (def, nullptr, nullptr)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
additional_properties::use (properties *ptr)
|
||||||
|
{
|
||||||
|
m_properties = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
additional_properties::use (pattern_properties *ptr)
|
||||||
|
{
|
||||||
|
m_patterns = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
additional_properties::output_iterator
|
additional_properties::output_iterator
|
||||||
additional_properties::validate (output_iterator res,
|
additional_properties::validate (output_iterator res,
|
||||||
@ -146,8 +195,15 @@ additional_properties::validate (output_iterator res,
|
|||||||
if (!target.is_object ())
|
if (!target.is_object ())
|
||||||
return *res++ = { .rule = *this, .target = target };
|
return *res++ = { .rule = *this, .target = target };
|
||||||
|
|
||||||
for (auto &[key,val]: target.as_object ())
|
for (auto &[key,val]: target.as_object ()) {
|
||||||
|
// don't check properties that are handled elsewhere
|
||||||
|
if (m_patterns && m_patterns->has (key))
|
||||||
|
continue;
|
||||||
|
if (m_properties && m_properties->has (key))
|
||||||
|
continue;
|
||||||
|
|
||||||
res = m_fallback.validate (res, *val);
|
res = m_fallback.validate (res, *val);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,8 @@ namespace util::json::schema::constraint {
|
|||||||
output_iterator validate (output_iterator, ::json::tree::node &target) const noexcept override;
|
output_iterator validate (output_iterator, ::json::tree::node &target) const noexcept override;
|
||||||
std::ostream& describe (std::ostream&) const override;
|
std::ostream& describe (std::ostream&) const override;
|
||||||
|
|
||||||
|
bool has (std::string const &key) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string,combine> m_properties;
|
std::map<std::string,combine> m_properties;
|
||||||
};
|
};
|
||||||
@ -47,6 +49,8 @@ namespace util::json::schema::constraint {
|
|||||||
output_iterator validate (output_iterator, ::json::tree::node &target) const noexcept override;
|
output_iterator validate (output_iterator, ::json::tree::node &target) const noexcept override;
|
||||||
std::ostream& describe (std::ostream&) const override;
|
std::ostream& describe (std::ostream&) const override;
|
||||||
|
|
||||||
|
bool has (std::string const &key) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct pattern_t {
|
struct pattern_t {
|
||||||
std::string pattern;
|
std::string pattern;
|
||||||
@ -65,6 +69,9 @@ namespace util::json::schema::constraint {
|
|||||||
|
|
||||||
virtual ~additional_properties () = default;
|
virtual ~additional_properties () = default;
|
||||||
|
|
||||||
|
void use (properties*);
|
||||||
|
void use (pattern_properties*);
|
||||||
|
|
||||||
output_iterator validate (output_iterator, ::json::tree::node &target) const noexcept override;
|
output_iterator validate (output_iterator, ::json::tree::node &target) const noexcept override;
|
||||||
std::ostream& describe (std::ostream&) const override;
|
std::ostream& describe (std::ostream&) const override;
|
||||||
|
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
null
|
@ -0,0 +1 @@
|
|||||||
|
{ "key": null }
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"key": {}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
{}
|
@ -0,0 +1 @@
|
|||||||
|
{ "key": "value" }
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"additionalProperties": { "type": "string" }
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
{ "int": "string" }
|
@ -0,0 +1 @@
|
|||||||
|
{ "bool": "string" }
|
@ -0,0 +1 @@
|
|||||||
|
{ "int": 0 }
|
@ -0,0 +1 @@
|
|||||||
|
{ "bool": true }
|
@ -0,0 +1 @@
|
|||||||
|
{ "key": "string" }
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"int": 0,
|
||||||
|
"bool": true,
|
||||||
|
"key": "string"
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"int": { "type": "integer" }
|
||||||
|
},
|
||||||
|
"patternProperties": {
|
||||||
|
"^bool": { "type": "boolean" }
|
||||||
|
},
|
||||||
|
"additionalProperties": { "type": "string" }
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user