Fix schema tests and added SchemaValidatingReader
This commit is contained in:
parent
6978f878eb
commit
05968b7031
@ -1869,6 +1869,21 @@ public:
|
||||
*/
|
||||
friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
|
||||
|
||||
//! Populate this document by a generator which produces SAX events.
|
||||
/*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.
|
||||
\param g Generator functor which sends SAX events to the parameter.
|
||||
\return The document itself for fluent API.
|
||||
*/
|
||||
template <typename Generator>
|
||||
GenericDocument& Populate(Generator& g) {
|
||||
ClearStackOnExit scope(*this);
|
||||
if (g(*this)) {
|
||||
RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
|
||||
ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!@name Parse from stream
|
||||
//!@{
|
||||
|
||||
@ -2017,9 +2032,10 @@ private:
|
||||
};
|
||||
|
||||
// callers of the following private Handler functions
|
||||
template <typename,typename,typename> friend class GenericReader; // for parsing
|
||||
// template <typename,typename,typename> friend class GenericReader; // for parsing
|
||||
template <typename, typename> friend class GenericValue; // for deep copying
|
||||
|
||||
public:
|
||||
// Implementation of Handler
|
||||
bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
|
||||
bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
|
||||
|
@ -18,6 +18,12 @@
|
||||
#include "../rapidjson.h"
|
||||
#include "stack.h"
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||
#endif
|
||||
|
||||
#ifndef RAPIDJSON_REGEX_VERBOSE
|
||||
#define RAPIDJSON_REGEX_VERBOSE 0
|
||||
#endif
|
||||
@ -639,4 +645,8 @@ typedef GenericRegex<UTF8<> > Regex;
|
||||
} // namespace internal
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_INTERNAL_REGEX_H_
|
||||
|
@ -19,6 +19,12 @@
|
||||
#include "pointer.h"
|
||||
#include <cmath> // HUGE_VAL, abs, floor
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(weak-vtables)
|
||||
RAPIDJSON_DIAG_OFF(exit-time-destructors)
|
||||
#endif
|
||||
|
||||
#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX)
|
||||
#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1
|
||||
#else
|
||||
@ -56,6 +62,11 @@ RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(variadic-macros)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -865,39 +876,39 @@ public:
|
||||
return v;\
|
||||
}
|
||||
|
||||
RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l');
|
||||
RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n');
|
||||
RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't');
|
||||
RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y');
|
||||
RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g');
|
||||
RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r');
|
||||
RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r');
|
||||
RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e');
|
||||
RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm');
|
||||
RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f');
|
||||
RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f');
|
||||
RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f');
|
||||
RAPIDJSON_STRING_(Not, 'n', 'o', 't');
|
||||
RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's');
|
||||
RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd');
|
||||
RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's');
|
||||
RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's');
|
||||
RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's');
|
||||
RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's');
|
||||
RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's');
|
||||
RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's');
|
||||
RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's');
|
||||
RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's');
|
||||
RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's');
|
||||
RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's');
|
||||
RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h');
|
||||
RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h');
|
||||
RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n');
|
||||
RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm');
|
||||
RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm');
|
||||
RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm');
|
||||
RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm');
|
||||
RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f');
|
||||
RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l')
|
||||
RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n')
|
||||
RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't')
|
||||
RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y')
|
||||
RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g')
|
||||
RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r')
|
||||
RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r')
|
||||
RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e')
|
||||
RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm')
|
||||
RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f')
|
||||
RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f')
|
||||
RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f')
|
||||
RAPIDJSON_STRING_(Not, 'n', 'o', 't')
|
||||
RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
|
||||
RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd')
|
||||
RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's')
|
||||
RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
|
||||
RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
|
||||
RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
|
||||
RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
|
||||
RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's')
|
||||
RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's')
|
||||
RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's')
|
||||
RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's')
|
||||
RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's')
|
||||
RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h')
|
||||
RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h')
|
||||
RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n')
|
||||
RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm')
|
||||
RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm')
|
||||
RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm')
|
||||
RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm')
|
||||
RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f')
|
||||
|
||||
#undef RAPIDJSON_STRING_
|
||||
|
||||
@ -1380,9 +1391,9 @@ private:
|
||||
if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) {
|
||||
PointerType pointer(&s[i], len - i, allocator_);
|
||||
if (pointer.IsValid()) {
|
||||
if (const SchemaType* s = remoteDocument->GetSchema(pointer)) {
|
||||
if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) {
|
||||
if (schema)
|
||||
*schema = s;
|
||||
*schema = sc;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1414,7 +1425,7 @@ private:
|
||||
|
||||
PointerType GetPointer(const SchemaType* schema) const {
|
||||
for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
|
||||
if (schema== target->schema)
|
||||
if (schema == target->schema)
|
||||
return target->pointer;
|
||||
return PointerType();
|
||||
}
|
||||
@ -1457,13 +1468,39 @@ public:
|
||||
schemaDocument_(&schemaDocument),
|
||||
root_(schemaDocument.GetRoot()),
|
||||
outputHandler_(nullOutputHandler_),
|
||||
stateAllocator_(allocator),
|
||||
ownStateAllocator_(0),
|
||||
schemaStack_(allocator, schemaStackCapacity),
|
||||
documentStack_(&GetStateAllocator(), documentStackCapacity),
|
||||
documentStack_(allocator, documentStackCapacity),
|
||||
valid_(true)
|
||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||
, depth_(0)
|
||||
#endif
|
||||
{
|
||||
CreateOwnAllocator();
|
||||
}
|
||||
|
||||
// Constructor with outputHandler
|
||||
GenericSchemaValidator(
|
||||
const SchemaDocumentType& schemaDocument,
|
||||
OutputHandler& outputHandler,
|
||||
StateAllocator* allocator = 0,
|
||||
size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
|
||||
size_t documentStackCapacity = kDefaultDocumentStackCapacity)
|
||||
:
|
||||
schemaDocument_(&schemaDocument),
|
||||
root_(schemaDocument.GetRoot()),
|
||||
outputHandler_(outputHandler),
|
||||
stateAllocator_(allocator),
|
||||
ownStateAllocator_(0),
|
||||
schemaStack_(allocator, schemaStackCapacity),
|
||||
documentStack_(allocator, documentStackCapacity),
|
||||
valid_(true)
|
||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||
, depth_(0)
|
||||
#endif
|
||||
{
|
||||
CreateOwnAllocator();
|
||||
}
|
||||
|
||||
~GenericSchemaValidator() {
|
||||
@ -1475,7 +1512,7 @@ public:
|
||||
PopSchema();
|
||||
//documentStack_.Clear();
|
||||
valid_ = true;
|
||||
};
|
||||
}
|
||||
|
||||
// Implementation of ISchemaValidator
|
||||
virtual bool IsValid() const { return valid_; }
|
||||
@ -1493,7 +1530,7 @@ public:
|
||||
}
|
||||
|
||||
StateAllocator& GetStateAllocator() {
|
||||
return schemaStack_.GetAllocator();
|
||||
return *stateAllocator_;
|
||||
}
|
||||
|
||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||
@ -1642,6 +1679,8 @@ private:
|
||||
schemaDocument_(&schemaDocument),
|
||||
root_(root),
|
||||
outputHandler_(nullOutputHandler_),
|
||||
stateAllocator_(allocator),
|
||||
ownStateAllocator_(0),
|
||||
schemaStack_(allocator, schemaStackCapacity),
|
||||
documentStack_(allocator, documentStackCapacity),
|
||||
valid_(true)
|
||||
@ -1649,6 +1688,12 @@ private:
|
||||
, depth_(depth)
|
||||
#endif
|
||||
{
|
||||
CreateOwnAllocator();
|
||||
}
|
||||
|
||||
void CreateOwnAllocator() {
|
||||
if (!stateAllocator_)
|
||||
stateAllocator_ = ownStateAllocator_ = new StateAllocator;
|
||||
}
|
||||
|
||||
bool BeginValue() {
|
||||
@ -1738,8 +1783,8 @@ private:
|
||||
void AppendToken(SizeType index) {
|
||||
*documentStack_.template Push<Ch>() = '/';
|
||||
char buffer[21];
|
||||
SizeType length = (sizeof(SizeType) == 4 ? internal::u32toa(index, buffer): internal::u64toa(index, buffer)) - buffer;
|
||||
for (SizeType i = 0; i < length; i++)
|
||||
size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer)) - buffer);
|
||||
for (size_t i = 0; i < length; i++)
|
||||
*documentStack_.template Push<Ch>() = buffer[i];
|
||||
}
|
||||
|
||||
@ -1762,8 +1807,10 @@ private:
|
||||
static const size_t kDefaultDocumentStackCapacity = 256;
|
||||
const SchemaDocumentType* schemaDocument_;
|
||||
const SchemaType& root_;
|
||||
BaseReaderHandler<EncodingType> nullOutputHandler_;
|
||||
OutputHandler nullOutputHandler_;
|
||||
OutputHandler& outputHandler_;
|
||||
StateAllocator* stateAllocator_;
|
||||
StateAllocator* ownStateAllocator_;
|
||||
internal::Stack<StateAllocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *)
|
||||
internal::Stack<StateAllocator> documentStack_; //!< stack to store the current path of validating document (Ch)
|
||||
bool valid_;
|
||||
@ -1774,10 +1821,62 @@ private:
|
||||
|
||||
typedef GenericSchemaValidator<SchemaDocument> SchemaValidator;
|
||||
|
||||
template <
|
||||
unsigned parseFlags,
|
||||
typename InputStream,
|
||||
typename SourceEncoding,
|
||||
typename SchemaDocumentType = SchemaDocument,
|
||||
typename StackAllocator = CrtAllocator>
|
||||
class SchemaValidatingReader {
|
||||
public:
|
||||
typedef typename SchemaDocumentType::PointerType PointerType;
|
||||
typedef typename InputStream::Ch Ch;
|
||||
|
||||
SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_() {}
|
||||
|
||||
template <typename Handler>
|
||||
bool operator()(Handler& handler) {
|
||||
GenericReader<SourceEncoding, typename SchemaDocumentType::EncodingType, StackAllocator> reader;
|
||||
GenericSchemaValidator<SchemaDocumentType, Handler> validator(sd_, handler);
|
||||
parseResult_ = reader.template Parse<parseFlags>(is_, validator);
|
||||
|
||||
if (validator.IsValid()) {
|
||||
invalidSchemaPointer_ = PointerType();
|
||||
invalidSchemaKeyword_ = 0;
|
||||
invalidDocumentPointer_ = PointerType();
|
||||
}
|
||||
else {
|
||||
invalidSchemaPointer_ = validator.GetInvalidSchemaPointer();
|
||||
invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword();
|
||||
invalidDocumentPointer_ = validator.GetInvalidDocumentPointer();
|
||||
}
|
||||
|
||||
return parseResult_;
|
||||
}
|
||||
|
||||
const ParseResult& GetParseResult() const { return parseResult_; }
|
||||
const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; }
|
||||
const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; }
|
||||
const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; }
|
||||
|
||||
private:
|
||||
InputStream& is_;
|
||||
const SchemaDocumentType& sd_;
|
||||
|
||||
ParseResult parseResult_;
|
||||
PointerType invalidSchemaPointer_;
|
||||
const Ch* invalidSchemaKeyword_;
|
||||
PointerType invalidDocumentPointer_;
|
||||
};
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#if defined(__GNUC__)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_SCHEMA_H_
|
||||
|
@ -16,6 +16,11 @@
|
||||
#include "rapidjson/schema.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(variadic-macros)
|
||||
#endif
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
#define TEST_HASHER(json1, json2, expected) \
|
||||
@ -95,7 +100,7 @@ TEST(SchemaValidator, Hasher) {
|
||||
{\
|
||||
SchemaValidator validator(schema);\
|
||||
Document d;\
|
||||
printf("\n%s\n", json);\
|
||||
/*printf("\n%s\n", json);*/\
|
||||
d.Parse(json);\
|
||||
EXPECT_FALSE(d.HasParseError());\
|
||||
EXPECT_TRUE(expected == d.Accept(validator));\
|
||||
@ -115,7 +120,7 @@ TEST(SchemaValidator, Hasher) {
|
||||
{\
|
||||
SchemaValidator validator(schema);\
|
||||
Document d;\
|
||||
printf("\n%s\n", json);\
|
||||
/*printf("\n%s\n", json);*/\
|
||||
d.Parse(json);\
|
||||
EXPECT_FALSE(d.HasParseError());\
|
||||
EXPECT_FALSE(d.Accept(validator));\
|
||||
@ -841,16 +846,16 @@ TEST(SchemaValidator, AllOf_Nested) {
|
||||
template <typename Allocator>
|
||||
static char* ReadFile(const char* filename, Allocator& allocator) {
|
||||
const char *paths[] = {
|
||||
"%s",
|
||||
"bin/%s",
|
||||
"../bin/%s",
|
||||
"../../bin/%s",
|
||||
"../../../bin/%s"
|
||||
"",
|
||||
"bin/",
|
||||
"../bin/",
|
||||
"../../bin/",
|
||||
"../../../bin/"
|
||||
};
|
||||
char buffer[1024];
|
||||
FILE *fp = 0;
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
|
||||
sprintf(buffer, paths[i], filename);
|
||||
sprintf(buffer, "%s%s", paths[i], filename);
|
||||
fp = fopen(buffer, "rb");
|
||||
if (fp)
|
||||
break;
|
||||
@ -860,9 +865,9 @@ static char* ReadFile(const char* filename, Allocator& allocator) {
|
||||
return 0;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t length = (size_t)ftell(fp);
|
||||
size_t length = static_cast<size_t>(ftell(fp));
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char* json = (char*)allocator.Malloc(length + 1);
|
||||
char* json = reinterpret_cast<char*>(allocator.Malloc(length + 1));
|
||||
size_t readLength = fread(json, 1, length, fp);
|
||||
json[readLength] = '\0';
|
||||
fclose(fp);
|
||||
@ -1087,4 +1092,39 @@ TEST(SchemaValidator, TestSuite) {
|
||||
printf("%d / %d passed (%2d%%)\n", passCount, testCount, passCount * 100 / testCount);
|
||||
// if (passCount != testCount)
|
||||
// ADD_FAILURE();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SchemaValidatingReader, Valid) {
|
||||
Document sd;
|
||||
sd.Parse("{ \"type\": \"string\", \"enum\" : [\"red\", \"amber\", \"green\"] }");
|
||||
SchemaDocument s(sd);
|
||||
|
||||
Document d;
|
||||
StringStream ss("\"red\"");
|
||||
SchemaValidatingReader<kParseDefaultFlags, StringStream, UTF8<> > reader(ss, s);
|
||||
d.Populate(reader);
|
||||
EXPECT_TRUE(reader.GetParseResult());
|
||||
EXPECT_TRUE(d.IsString());
|
||||
EXPECT_STREQ("red", d.GetString());
|
||||
}
|
||||
|
||||
TEST(SchemaValidatingReader, Invalid) {
|
||||
Document sd;
|
||||
sd.Parse("{\"type\":\"string\",\"minLength\":2,\"maxLength\":3}");
|
||||
SchemaDocument s(sd);
|
||||
|
||||
Document d;
|
||||
StringStream ss("\"ABCD\"");
|
||||
SchemaValidatingReader<kParseDefaultFlags, StringStream, UTF8<> > reader(ss, s);
|
||||
d.Populate(reader);
|
||||
EXPECT_FALSE(reader.GetParseResult());
|
||||
EXPECT_EQ(kParseErrorTermination, reader.GetParseResult().Code());
|
||||
EXPECT_STREQ("maxLength", reader.GetInvalidSchemaKeyword());
|
||||
EXPECT_TRUE(reader.GetInvalidSchemaPointer() == SchemaDocument::PointerType(""));
|
||||
EXPECT_TRUE(reader.GetInvalidDocumentPointer() == SchemaDocument::PointerType(""));
|
||||
EXPECT_TRUE(d.IsNull());
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
@ -28,4 +28,4 @@ TEST(StrFunc, CountStringCodePoint) {
|
||||
EXPECT_TRUE(CountStringCodePoint<UTF8<> >("\xC2\xA2\xE2\x82\xAC\xF0\x9D\x84\x9E", 9, &count)); // cents euro G-clef
|
||||
EXPECT_EQ(3u, count);
|
||||
EXPECT_FALSE(CountStringCodePoint<UTF8<> >("\xC2\xA2\xE2\x82\xAC\xF0\x9D\x84\x9E\x80", 10, &count));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user