summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/model/Document.cpp43
-rw-r--r--test/core/model/DocumentTest.cpp82
2 files changed, 119 insertions, 6 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp
index e9b6136..a6bcb15 100644
--- a/src/core/model/Document.cpp
+++ b/src/core/model/Document.cpp
@@ -157,6 +157,32 @@ bool DocumentEntity::doValidate(Logger &logger) const
}
// iterate over every field
for (unsigned int f = 0; f < fields.size(); f++) {
+ // we have a special check for primitive fields.
+ if (fieldDescs[f]->getFieldType() ==
+ FieldDescriptor::FieldType::PRIMITIVE) {
+ switch (fields[f].size()) {
+ case 0:
+ if (!fieldDescs[f]->optional) {
+ logger.error(std::string("Primitive Field \"") +
+ fieldDescs[f]->getName() +
+ "\" had no content!");
+ valid = false;
+ }
+ continue;
+ case 1:
+ break;
+ default:
+ logger.error(std::string("Primitive Field \"") +
+ fieldDescs[f]->getName() +
+ "\" had more than one child!");
+ valid = false;
+ continue;
+ }
+ // if we are here we know that exactly one child exists.
+ // TODO: Check the primitive type of the child.
+ continue;
+ }
+
// we can do a faster check if this field is empty.
if (fields[f].size() == 0) {
// if this field is optional, an empty field is valid anyways.
@@ -197,8 +223,10 @@ bool DocumentEntity::doValidate(Logger &logger) const
continue;
}
if (rc->isa(RttiTypes::DocumentPrimitive)) {
- // For DocumentPrimitives we have to check the content type.
- // TODO: Do that!
+ logger.error(std::string("Non-primitive Field \"") +
+ fieldDescs[f]->getName() +
+ "\" had primitive content!");
+ valid = false;
continue;
}
// otherwise this is a StructuredEntity
@@ -322,6 +350,7 @@ AnnotationEntity::AnnotationEntity(Manager &mgr, Handle<Document> parent,
end(acquire(end))
{
parent->annotations.push_back(this);
+ parent->invalidate();
}
bool AnnotationEntity::doValidate(Logger &logger) const
@@ -352,12 +381,18 @@ bool AnnotationEntity::doValidate(Logger &logger) const
valid = valid & validateName(logger);
}
// check if the Anchors are part of the right document.
- if (!doc->hasChild(start)) {
+ if (start == nullptr) {
+ logger.error("This annotation has no start Anchor!");
+ valid = false;
+ } else if (!doc->hasChild(start)) {
logger.error(
"This annotations start anchor was not part of the same document!");
valid = false;
}
- if (!doc->hasChild(end)) {
+ if (end == nullptr) {
+ logger.error("This annotation has no end Anchor!");
+ valid = false;
+ } else if (!doc->hasChild(end)) {
logger.error(
"This annotations end anchor was not part of the same document!");
valid = false;
diff --git a/test/core/model/DocumentTest.cpp b/test/core/model/DocumentTest.cpp
index d8ccef1..fea5296 100644
--- a/test/core/model/DocumentTest.cpp
+++ b/test/core/model/DocumentTest.cpp
@@ -134,6 +134,14 @@ TEST(Document, validate)
buildRootStructuredEntity(doc, logger, {"root"});
ASSERT_TRUE(doc->validate(logger));
}
+ {
+ // A root with an invalid name, however, should make it invalid
+ Rooted<Document> doc{new Document(mgr, "myDoc.oxd")};
+ doc->addDomain(domain);
+ Rooted<StructuredEntity> root = buildRootStructuredEntity(
+ doc, logger, {"root"}, {}, "my invalid root");
+ ASSERT_FALSE(doc->validate(logger));
+ }
// now let's extend the rootClass with a default field.
Rooted<FieldDescriptor> rootField{new FieldDescriptor(mgr, rootClass)};
@@ -192,8 +200,78 @@ TEST(Document, validate)
buildStructuredEntity(doc, logger, root, {"childSub"});
ASSERT_FALSE(doc->validate(logger));
}
- // TODO: Override child field in childSub such that an empty childSub is
- // valid.
+ /*
+ * Override the default field in childSubClass.
+ */
+ Rooted<FieldDescriptor> childSubField{
+ new FieldDescriptor(mgr, childSubClass)};
+ {
+ /*
+ * Now a document with one instance of the Child subclass should be
+ * valid, because of the override.
+ */
+ Rooted<Document> doc{new Document(mgr, "myDoc.oxd")};
+ doc->addDomain(domain);
+ Rooted<StructuredEntity> root =
+ buildRootStructuredEntity(doc, logger, {"root"});
+ buildStructuredEntity(doc, logger, root, {"childSub"});
+ ASSERT_TRUE(doc->validate(logger));
+ }
+ // add a primitive field to the subclass with integer content.
+ Rooted<FieldDescriptor> primitive_field{new FieldDescriptor(
+ mgr, childSubClass, sys->getIntType(), "int", false)};
+ {
+ /*
+ * Now a document with one instance of the Child subclass should be
+ * invalid again, because we are missing the primitive content.
+ */
+ Rooted<Document> doc{new Document(mgr, "myDoc.oxd")};
+ doc->addDomain(domain);
+ Rooted<StructuredEntity> root =
+ buildRootStructuredEntity(doc, logger, {"root"});
+ buildStructuredEntity(doc, logger, root, {"childSub"});
+ ASSERT_FALSE(doc->validate(logger));
+ }
+ // TODO: Check wrongly typed primitive content.
+
+ // Now add an Annotation class to the domain.
+ Rooted<AnnotationClass> annoClass{new AnnotationClass(mgr, "anno", domain)};
+ {
+ /*
+ * Create a valid document in itself.
+ */
+ Rooted<Document> doc{new Document(mgr, "myDoc.oxd")};
+ doc->addDomain(domain);
+ Rooted<StructuredEntity> root =
+ buildRootStructuredEntity(doc, logger, {"root"});
+ Rooted<StructuredEntity> child =
+ buildStructuredEntity(doc, logger, root, {"childSub"});
+ Rooted<DocumentPrimitive> primitive{
+ new DocumentPrimitive(mgr, child, {2}, "int")};
+ ASSERT_TRUE(doc->validate(logger));
+ // then add an AnnotationEntity without Anchors.
+ buildAnnotationEntity(doc, logger, {"anno"}, nullptr, nullptr);
+ ASSERT_FALSE(doc->validate(logger));
+ }
+ {
+ /*
+ * Do the same again, but with a valid AnnotationEntity now.
+ */
+ Rooted<Document> doc{new Document(mgr, "myDoc.oxd")};
+ doc->addDomain(domain);
+ Rooted<StructuredEntity> root =
+ buildRootStructuredEntity(doc, logger, {"root"});
+ Rooted<Anchor> start{new Anchor(mgr, "start", root)};
+ Rooted<StructuredEntity> child =
+ buildStructuredEntity(doc, logger, root, {"childSub"});
+ Rooted<DocumentPrimitive> primitive{
+ new DocumentPrimitive(mgr, child, {2}, "int")};
+ Rooted<Anchor> end{new Anchor(mgr, "end", root)};
+ ASSERT_TRUE(doc->validate(logger));
+ // then add an AnnotationEntity without Anchors.
+ buildAnnotationEntity(doc, logger, {"anno"}, start, end);
+ ASSERT_TRUE(doc->validate(logger));
+ }
}
}
}