TEST(ModelBase, VisitorSample) { Model model; List* root = dynamic_cast<List*> (model.createRoot("List")); model.setName("root"); model.beginModification(root, "make tree"); root->append(new Text("hello")); auto i = new Integer(); i->set(42); root->append( i); model.endModification(); VisitorA::init(); auto visA = new VisitorA(); QString valA = visA->visit(root); delete visA; VisitorB::init(); auto visB = new VisitorB(); QString valB = visB->visit(root); delete visB; VisitorC::init(); auto visC = new VisitorC(); visC->visit(root); QString valC = visC->text; delete visC; CHECK_STR_EQUAL("List(Text,Node,)", valA); CHECK_STR_EQUAL("List(hello,42,)", valB); CHECK_STR_EQUAL("hello42", valC); CHECK_CONDITION( true ); }
TEST(ModelBase, PersistenceSave) { Model model; PersistentStoreMock store; TestNodes::BinaryNode* root = dynamic_cast<TestNodes::BinaryNode*> (model.createRoot("BinaryNode")); model.setName("root"); model.save(&store); CHECK_STR_EQUAL("BinaryNode,root,full,Text,name,full,,Integer,_ext_PositionExtension_x,full,0,Integer,_ext_PositionExtension_y,full,0,", store.getSaved()); model.beginModification(root, "make tree"); root->setLeft(new TestNodes::BinaryNode()); root->setRight( new TestNodes::BinaryNode()); root->name()->set("Troot"); root->left()->name()->set("Tleft"); root->right()->name()->set("Tright"); model.endModification(); store.clear(); model.save(); CHECK_STR_EQUAL("BinaryNode,root,full,Text,name,full,Troot,BinaryNode,left,full,Text,name,full,Tleft,Integer,_ext_PositionExtension_x,full,0,Integer,_ext_PositionExtension_y,full,0,BinaryNode,right,full,Text,name,full,Tright,Integer,_ext_PositionExtension_x,full,0,Integer,_ext_PositionExtension_y,full,0,Integer,_ext_PositionExtension_x,full,0,Integer,_ext_PositionExtension_y,full,0,", store.getSaved()); }
TEST(FilePersistence, LoadMultipleUnits) { QString testDir = ":/FilePersistence/test/persisted"; Model::Model model; FileStore store; store.setBaseFolder(testDir); model.load(&store, "units"); TestNodes::BinaryNode* root = dynamic_cast<TestNodes::BinaryNode*> (model.root()); CHECK_STR_EQUAL("BinaryNode", root->typeName() ); CHECK_STR_EQUAL("Root", root->name()->get() ); CHECK_CONDITION(root->left() != nullptr); CHECK_CONDITION(root->right() != nullptr); CHECK_STR_EQUAL("BinaryNodePersistenceUnit", root->left()->typeName() ); CHECK_STR_EQUAL("Left child", root->left()->name()->get() ); CHECK_CONDITION(root->left()->left() != nullptr); CHECK_CONDITION(root->left()->right() == nullptr); CHECK_STR_EQUAL("BinaryNode", root->left()->left()->typeName() ); CHECK_STR_EQUAL("in a new unit", root->left()->left()->name()->get() ); CHECK_CONDITION(root->left()->left()->left() == nullptr); CHECK_CONDITION(root->left()->left()->right() == nullptr); CHECK_STR_EQUAL("BinaryNode", root->right()->typeName() ); CHECK_STR_EQUAL("Right child", root->right()->name()->get() ); CHECK_CONDITION(root->right()->left() == nullptr); CHECK_CONDITION(root->right()->right() == nullptr); }
TEST(FilePersistence, LoadRootOnly) { QString testDir = ":/FilePersistence/test/persisted"; Model::Model model; FileStore store; store.setBaseFolder(testDir); model.load(&store, "rootOnly"); TestNodes::BinaryNode* root = dynamic_cast<TestNodes::BinaryNode*> (model.root()); CHECK_CONDITION(root); CHECK_STR_EQUAL("BinaryNode", root->typeName() ); CHECK_STR_EQUAL("Title", root->name()->get() ); CHECK_CONDITION(root->left() == nullptr); CHECK_CONDITION(root->right() == nullptr); }
TEST(FilePersistence, LoadingList) { QString testDir = ":/FilePersistence/test/persisted"; Model::Model model; FileStore store; store.setBaseFolder(testDir); model.load(&store, "partial"); TestNodes::PartialList* root = dynamic_cast<TestNodes::PartialList*> (model.root()); CHECK_CONDITION(root != nullptr); Model::List* list = root->list(); CHECK_CONDITION(list != nullptr); CHECK_STR_EQUAL("List", list->typeName() ); CHECK_CONDITION(list->isFullyLoaded() == false); CHECK_INT_EQUAL(1, list->id()); list->loadFully(store); CHECK_CONDITION(list->isFullyLoaded()); CHECK_INT_EQUAL(4, list->size()); Model::Text* one = list->at<Model::Text>(0); Model::Text* two = list->at<Model::Text>(1); Model::Text* three = list->at<Model::Text>(2); Model::Text* four = list->at<Model::Text>(3); CHECK_CONDITION(one != nullptr); CHECK_STR_EQUAL("one", one->get()); CHECK_INT_EQUAL(2, one->id()); CHECK_CONDITION(two != nullptr); CHECK_STR_EQUAL("two", two->get()); CHECK_INT_EQUAL(3, two->id()) CHECK_CONDITION(three != nullptr); CHECK_STR_EQUAL("three", three->get()); CHECK_INT_EQUAL(4, three->id()) CHECK_CONDITION(four != nullptr); CHECK_STR_EQUAL("four", four->get()); CHECK_INT_EQUAL(5, four->id()); }
TEST(OOModel, SimpleProjectTest) { Model::Model model; Project* root = dynamic_cast<Project*> (model.createRoot("Project")); CHECK_CONDITION(root != nullptr); CHECK_CONDITION(root->name().isEmpty()); model.beginModification(root, "setName"); root->setName("prj"); model.endModification(); CHECK_STR_EQUAL("prj", root->name()); }
TEST(OOModel, SimpleClassTest) { Model::Model model; Class* root = dynamic_cast<Class*> (model.createRoot("Class")); CHECK_CONDITION(root != nullptr); CHECK_CONDITION(root->name().isEmpty()); model.beginModification(root, "setName"); root->setName("Test"); model.endModification(); CHECK_STR_EQUAL("Test", root->name()); }
TEST(FilePersistence, LoadingTypedList) { QString testDir = ":/FilePersistence/test/persisted"; Model::Model model; FileStore store; store.setBaseFolder(testDir); model.load(&store, "typedList"); Model::TypedList<Model::Text>* list = dynamic_cast<Model::TypedList<Model::Text>*> (model.root()); CHECK_CONDITION(list != nullptr); CHECK_STR_EQUAL("TypedListOfText", list->typeName() ); CHECK_INT_EQUAL(2, list->size()); Model::Text* one = list->at(0); Model::Text* two = list->at(1); CHECK_CONDITION(one != nullptr); CHECK_STR_EQUAL("one", one->get()); CHECK_CONDITION(two != nullptr); CHECK_STR_EQUAL("two", two->get()); }
TEST(ModelBase, CompositeMetaData) { AttributeChain& metaExt = TestNodes::BinaryNode::getMetaData(); AttributeChain& metaUnit = TestNodes::BinaryNodeAccessUnit::getMetaData(); CHECK_INT_EQUAL(1, metaExt.numLevels()); CHECK_INT_EQUAL(2, metaUnit.numLevels()); CHECK_INT_EQUAL(5, metaExt.size()); CHECK_INT_EQUAL(0, metaUnit.size()); CHECK_CONDITION( metaUnit.level(0) == &metaExt); CHECK_STR_EQUAL("name", metaExt[0].name()); CHECK_STR_EQUAL("left", metaExt[1].name()); CHECK_STR_EQUAL("right", metaExt[2].name()); CHECK_STR_EQUAL("_ext_PositionExtension_x", metaExt[3].name()); CHECK_STR_EQUAL("_ext_PositionExtension_y", metaExt[4].name()); CHECK_STR_EQUAL("Text", metaExt[0].type()); CHECK_STR_EQUAL("BinaryNode", metaExt[1].type()); CHECK_STR_EQUAL("BinaryNode", metaExt[2].type()); CHECK_STR_EQUAL("Integer", metaExt[3].type()); CHECK_STR_EQUAL("Integer", metaExt[4].type()); CHECK_CONDITION(metaExt[0].optional() == false); CHECK_CONDITION(metaExt[1].optional() == true); CHECK_CONDITION(metaExt[2].optional() == true); CHECK_CONDITION(metaExt[3].optional() == false); CHECK_CONDITION(metaExt[4].optional() == false); CHECK_CONDITION(metaExt[0].partialHint() == false); CHECK_CONDITION(metaExt[1].partialHint() == false); CHECK_CONDITION(metaExt[2].partialHint() == false); CHECK_CONDITION(metaExt[3].partialHint() == false); CHECK_CONDITION(metaExt[4].partialHint() == false); }
TEST(OOModel, JavaLibraryAndHelloWorldTest) { Model::Model model; Project* prj = dynamic_cast<Project*> (model.createRoot("Project")); model.beginModification(prj, "build simple java library and a hello world app"); prj->setName("HelloWorld"); // Build a simple Java Library Library* java = prj->libraries()->append<Library>(); java->setName("Java"); Class* string = java->classes()->append<Class>(); string->setName("String"); string->setVisibility(Visibility::PUBLIC); Module* io = java->modules()->append<Module>(); io->setName("io"); Class* printstream = io->classes()->append<Class>(); printstream->setName("PrintStream"); printstream->setVisibility(Visibility::PUBLIC); Method* println = printstream->methods()->append<Method>(); println->setName("println"); println->setVisibility(Visibility::PUBLIC); FormalArgument* arg = println->arguments()->append<FormalArgument>(); arg->setName("x"); NamedType* argType = arg->setType<NamedType>(); argType->type()->ref()->set("class:String"); Class* system = java->classes()->append<Class>(); system->setName("System"); system->setVisibility(Visibility::PUBLIC); Field* out = system->fields()->append<Field>(); out->setName("out"); out->setVisibility(Visibility::PUBLIC); out->setStorageSpecifier(StorageSpecifier::CLASS_VARIABLE); NamedType* outtype = out->setType<NamedType>(); outtype->type()->ref()->set("class:PrintStream"); outtype->type()->setPrefix<ReferenceExpression>()->ref()->set("mod:io"); // Build a simple HelloWorld Application Class* hello = prj->classes()->append<Class>(); hello->setName("HelloWorld"); hello->setVisibility(Visibility::PUBLIC); Method* main = hello->methods()->append<Method>(); main->setName("main"); main->setVisibility(Visibility::PUBLIC); main->setStorageSpecifier(StorageSpecifier::CLASS_VARIABLE); //TODO make an array argument MethodCallStatement* callPrintln = main->items()->append<MethodCallStatement>(); StringLiteral* helloStr = callPrintln->arguments()->append<StringLiteral>(); helloStr->setValue("Hello World"); callPrintln->ref()->set("met:println"); VariableAccess* va = callPrintln->setPrefix<VariableAccess>(); va->ref()->set("field:out"); ReferenceExpression* ref = va->setPrefix<ReferenceExpression>(); ref->ref()->set("lib:Java,class:System"); model.endModification(); CHECK_STR_EQUAL("Java", java->name()); CHECK_CONDITION(callPrintln->methodDefinition() != nullptr); CHECK_CONDITION(callPrintln->methodDefinition() == println); }
TEST(FilePersistence, LoadDataMultipleUnits) { QString testDir = ":/FilePersistence/test/persisted"; FileStore store; store.setBaseFolder(testDir); typedef PersistedValue< QString >* String; typedef PersistedValue< QList<PersistedNode*> >* Composite; // Root Node Composite root = dynamic_cast<Composite> (store.loadCompleteNodeSubtree("units", nullptr)); CHECK_CONDITION(root); CHECK_STR_EQUAL("BinaryNode", root->type() ); CHECK_STR_EQUAL("units", root->name()); CHECK_INT_EQUAL(0, root->id()); CHECK_CONDITION(!root->partialHint()); CHECK_CONDITION(!root->isNewPersistenceUnit()); CHECK_INT_EQUAL(3, root->value().size()); // Root Node children String rootName = dynamic_cast<String> (root->value().at(0)); CHECK_CONDITION(rootName); CHECK_STR_EQUAL("Text", rootName->type() ); CHECK_STR_EQUAL("name", rootName->name()); CHECK_INT_EQUAL(1, rootName->id()); CHECK_CONDITION(!rootName->partialHint()); CHECK_CONDITION(!rootName->isNewPersistenceUnit()); CHECK_STR_EQUAL("Root", rootName->value()); Composite left = dynamic_cast<Composite> (root->value().at(1)); CHECK_CONDITION(left); CHECK_STR_EQUAL("BinaryNodePersistenceUnit", left->type() ); CHECK_STR_EQUAL("left", left->name()); CHECK_INT_EQUAL(2, left->id()); CHECK_CONDITION(!left->partialHint()); CHECK_CONDITION(left->isNewPersistenceUnit()); CHECK_INT_EQUAL(2, left->value().size()); Composite right = dynamic_cast<Composite> (root->value().at(2)); CHECK_CONDITION(right); CHECK_STR_EQUAL("BinaryNode", right->type() ); CHECK_STR_EQUAL("right", right->name()); CHECK_INT_EQUAL(6, right->id()); CHECK_CONDITION(!right->partialHint()); CHECK_CONDITION(!right->isNewPersistenceUnit()); CHECK_INT_EQUAL(1, right->value().size()); // Left Node children String leftName = dynamic_cast<String> (left->value().at(0)); CHECK_CONDITION(leftName); CHECK_STR_EQUAL("Text", leftName->type() ); CHECK_STR_EQUAL("name", leftName->name()); CHECK_INT_EQUAL(3, leftName->id()); CHECK_CONDITION(!leftName->partialHint()); CHECK_CONDITION(!leftName->isNewPersistenceUnit()); CHECK_STR_EQUAL("Left child", leftName->value()); Composite leftleft = dynamic_cast<Composite> (left->value().at(1)); CHECK_CONDITION(leftleft); CHECK_STR_EQUAL("BinaryNode", leftleft->type() ); CHECK_STR_EQUAL("left", leftleft->name()); CHECK_INT_EQUAL(4, leftleft->id()); CHECK_CONDITION(!leftleft->partialHint()); CHECK_CONDITION(!leftleft->isNewPersistenceUnit()); CHECK_INT_EQUAL(1, leftleft->value().size()); String leftleftName = dynamic_cast<String> (leftleft->value().at(0)); CHECK_CONDITION(leftleftName); CHECK_STR_EQUAL("Text", leftleftName->type() ); CHECK_STR_EQUAL("name", leftleftName->name()); CHECK_INT_EQUAL(5, leftleftName->id()); CHECK_CONDITION(!leftleftName->partialHint()); CHECK_CONDITION(!leftleftName->isNewPersistenceUnit()); CHECK_STR_EQUAL("in a new unit", leftleftName->value()); // Right Node children String rightName = dynamic_cast<String> (right->value().at(0)); CHECK_CONDITION(rightName); CHECK_STR_EQUAL("Text", rightName->type() ); CHECK_STR_EQUAL("name", rightName->name()); CHECK_INT_EQUAL(7, rightName->id()); CHECK_CONDITION(!rightName->partialHint()); CHECK_CONDITION(!rightName->isNewPersistenceUnit()); CHECK_STR_EQUAL("Right child", rightName->value()); }
TEST(ModelBase, SingleWriteUnitCheck) { Model model; TestNodes::BinaryNode* root = dynamic_cast<TestNodes::BinaryNode*> (model.createRoot("BinaryNode")); model.beginModification(root, "make tree"); TestNodes::BinaryNode* left = root->setLeft<TestNodes::BinaryNode>(); TestNodes::BinaryNode* right = root->setRight<TestNodes::BinaryNodeAccessUnit>(); TestNodes::BinaryNode* one = root->left()->setLeft<TestNodes::BinaryNodeAccessUnit>(); TestNodes::BinaryNode* two = root->left()->setRight<TestNodes::BinaryNodeAccessUnit>(); model.endModification(); CHECK_STR_EQUAL(QString(), root->name()->get()); CHECK_STR_EQUAL(QString(), left->name()->get()); CHECK_STR_EQUAL(QString(), right->name()->get()); CHECK_STR_EQUAL(QString(), one->name()->get()); CHECK_STR_EQUAL(QString(), two->name()->get()); model.beginModification(root, "Modify root"); root->name()->set("This is ok"); CHECK_STR_EQUAL("This is ok", root->name()->get()); CHECK_FOR_EXCEPTION(ModelException, one->name()->set("This should fail")); CHECK_STR_EQUAL(QString(), one->name()->get()); model.changeModificationTarget(one); CHECK_FOR_EXCEPTION(ModelException, root->name()->set("This should fail")); CHECK_STR_EQUAL("This is ok", root->name()->get()); one->name()->set("one set"); CHECK_STR_EQUAL("one set", one->name()->get()); model.endModification(); model.beginModification(nullptr); model.undo(); model.endModification(); CHECK_STR_EQUAL(QString(), root->name()->get()); CHECK_STR_EQUAL(QString(), left->name()->get()); CHECK_STR_EQUAL(QString(), right->name()->get()); CHECK_STR_EQUAL(QString(), one->name()->get()); CHECK_STR_EQUAL(QString(), two->name()->get()); model.beginModification(nullptr); model.redo(); model.endModification(); CHECK_STR_EQUAL("This is ok", root->name()->get()); CHECK_STR_EQUAL(QString(), left->name()->get()); CHECK_STR_EQUAL(QString(), right->name()->get()); CHECK_STR_EQUAL("one set", one->name()->get()); CHECK_STR_EQUAL(QString(), two->name()->get()); }