/* Ousía Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "TestDocument.hpp" #include "TestDomain.hpp" namespace ousia { namespace model { TEST(Document, construct) { // Construct Manager TerminalLogger logger{std::cerr, true}; Manager mgr{1}; Rooted sys{new SystemTypesystem(mgr)}; // Get the domain. Rooted domain = constructBookDomain(mgr, sys, logger); // Construct the document. Rooted doc = constructBookDocument(mgr, logger, domain); // Check the document content. ASSERT_FALSE(doc.isNull()); // get root node. Rooted root = doc->getRoot(); ASSERT_FALSE(root.isNull()); ASSERT_EQ("book", root->getDescriptor()->getName()); ASSERT_TRUE(root->hasField()); ASSERT_EQ(2U, root->getField().size()); // get foreword (paragraph) { Rooted foreword = root->getField()[0].cast(); ASSERT_FALSE(foreword.isNull()); ASSERT_EQ("paragraph", foreword->getDescriptor()->getName()); // it should contain one text node ASSERT_TRUE(foreword->hasField()); ASSERT_EQ(1U, foreword->getField().size()); // which in turn should have a primitive content field containing the // right text. { Rooted text = foreword->getField()[0].cast(); ASSERT_FALSE(text.isNull()); ASSERT_EQ("text", text->getDescriptor()->getName()); ASSERT_TRUE(text->hasField()); ASSERT_EQ(1U, text->getField().size()); ASSERT_TRUE(text->getField()[0]->isa(typeOf())); Variant content = text->getField()[0].cast()->getContent(); ASSERT_EQ("Some introductory text", content.asString()); } } // get section { Rooted section = root->getField()[1].cast(); ASSERT_FALSE(section.isNull()); ASSERT_EQ("section", section->getDescriptor()->getName()); // it should contain one paragraph ASSERT_TRUE(section->hasField()); ASSERT_EQ(1U, section->getField().size()); { Rooted par = section->getField()[0].cast(); ASSERT_FALSE(par.isNull()); ASSERT_EQ("paragraph", par->getDescriptor()->getName()); // it should contain one text node ASSERT_TRUE(par->hasField()); ASSERT_EQ(1U, par->getField().size()); // which in turn should have a primitive content field containing // the right text. { Rooted text = par->getField()[0].cast(); ASSERT_FALSE(text.isNull()); ASSERT_EQ("text", text->getDescriptor()->getName()); ASSERT_TRUE(text->hasField()); ASSERT_EQ(1U, text->getField().size()); ASSERT_TRUE( text->getField()[0]->isa(typeOf())); Variant content = text->getField()[0].cast()->getContent(); ASSERT_EQ("Some actual text", content.asString()); } } } } TEST(Document, validate) { // Let's start with a trivial domain and a trivial document. TerminalLogger logger{std::cerr, true}; Manager mgr{1}; Rooted sys{new SystemTypesystem(mgr)}; Rooted domain{new Domain(mgr, sys, "trivial")}; Cardinality single; single.merge({1}); // Set up the "root" StructuredClass. Rooted rootClass{new StructuredClass( mgr, "root", domain, single, {nullptr}, {nullptr}, false, true)}; // set up a document for it. { // first an invalid one, which is empty. Rooted doc{new Document(mgr, "myDoc.oxd")}; doc->addDomain(domain); ASSERT_FALSE(doc->validate(logger)); // then add a root, which should make it valid. Rooted root = buildRootStructuredEntity(doc, logger, {"root"}); ASSERT_TRUE(doc->validate(logger)); } // now let's extend the rootClass with a default field. Rooted rootField{new FieldDescriptor(mgr, rootClass)}; // and add a child class for it. Rooted childClass{ new StructuredClass(mgr, "child", domain, single)}; rootField->addChild(childClass); { /* * now check again: Because the child has the cardinality {1} our * document should be invalid again. */ Rooted doc{new Document(mgr, "myDoc.oxd")}; doc->addDomain(domain); Rooted root = buildRootStructuredEntity(doc, logger, {"root"}); ASSERT_FALSE(doc->validate(logger)); // but it should get valid if we add a proper child. buildStructuredEntity(doc, logger, root, {"child"}); ASSERT_TRUE(doc->validate(logger)); // and it should get invalid again if we add one more child. buildStructuredEntity(doc, logger, root, {"child"}); ASSERT_FALSE(doc->validate(logger)); } /* * Add a further extension to the domain: We add a subclass to child. */ Rooted childSubClass{new StructuredClass( mgr, "childSub", domain, single, {nullptr}, childClass)}; { /* * A document with one instance of the Child subclass should be valid. */ Rooted doc{new Document(mgr, "myDoc.oxd")}; doc->addDomain(domain); Rooted root = buildRootStructuredEntity(doc, logger, {"root"}); buildStructuredEntity(doc, logger, root, {"childSub"}); ASSERT_TRUE(doc->validate(logger)); } /* * Make it even more complicated: child gets a field for further child * instances now. */ Rooted childField{new FieldDescriptor(mgr, childClass)}; childField->addChild(childClass); { /* * Now a document with one instance of the Child subclass should be * invalid, because it has no children of itself. */ Rooted doc{new Document(mgr, "myDoc.oxd")}; doc->addDomain(domain); Rooted root = buildRootStructuredEntity(doc, logger, {"root"}); buildStructuredEntity(doc, logger, root, {"childSub"}); ASSERT_FALSE(doc->validate(logger)); } // TODO: Override child field in childSub such that an empty childSub is // valid. } } }