#include #include #include "CodeDweller/XMLReader.hpp" //////////////////////////////////////////////////////////////////////////////// // Configuration /////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // End of configuration //////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int nTotalTests = 0; int nPass = 0; int nFail = 0; bool result; #define NO_EXCEPTION_TERM(msg) \ std::cout \ << msg << " failed to throw exception at line " \ << __LINE__ << "." << std::endl #define EXCEPTION_TERM(msg) \ std::cout \ << msg << " threw unexpected exception: " << e.what() << std::endl #define RETURN_FALSE(msg) \ std::cout \ << msg << " at line " << __LINE__ << std::endl; \ return false; #define RUN_TEST(test) \ std::cout << " " #test ": "; \ std::cout.flush(); \ result = test(); \ std::cout << (result ? "ok" : "fail") << std::endl; \ nTotalTests++; \ if (result) nPass++; else nFail++; #define SUMMARY \ std::cout \ << "\nPass: " << nPass \ << ", Fail: " << nFail \ << ", Total: " << nTotalTests << std::endl //////////////////////////////////////////////////////////////////////////////// // Tests /////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// bool testEmptyElement() { std::string stageContent, stage1Content, stage2Content; std::string elementXml, element1Xml, element2Xml; CodeDweller::XMLReaderElement reader("elem"); reader .Element("stage", stageContent) .RawData(elementXml) .End("stage") .Element("stage1", stage1Content) .RawData(element1Xml) .End("stage1") .Element("stage2", stage2Content) .RawData(element2Xml) .End("stage2") .End("elem"); std::string xml; xml = ""; CodeDweller::XMLReaderData confData(xml.data(), xml.size()); reader.initialize(); if (0 == reader.interpret(confData)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if (!(stageContent.empty() && stage1Content.empty() && stage2Content.empty())) { RETURN_FALSE("empty element 1 read failure"); } xml = ""; CodeDweller::XMLReaderData confData1(xml.data(), xml.size()); reader.initialize(); if (0 == reader.interpret(confData1)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if (!(stageContent.empty() && stage1Content.empty() && stage2Content.empty())) { RETURN_FALSE("empty element 2 read failure"); } xml = "Should be abc ignored"; CodeDweller::XMLReaderData confData2(xml.data(), xml.size()); reader.initialize(); if (0 == reader.interpret(confData2)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if (!(stageContent.empty() && stage1Content.empty() && stage2Content.empty())) { RETURN_FALSE("empty element 3 read failure"); } return true; } bool testRawData() { std::string stageContent; std::string elementXml, stageXml; CodeDweller::XMLReaderElement reader("elem"); reader .RawData(elementXml) .Element("stage", stageContent) .RawData(stageXml) .End("stage") .End("elem"); std::string xml; xml = "Content"; CodeDweller::XMLReaderData confData(xml.data(), xml.size()); reader.initialize(); if (0 == reader.interpret(confData)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if (elementXml != xml) { std::cout << "\nExpected: '" << xml << "'\n" << "Got: '" << elementXml << "'\n"; RETURN_FALSE("RawData() failure for root element"); } if ("Content" != stageXml) { RETURN_FALSE("RawData() failure for child element"); } if ("Content" != stageContent) { RETURN_FALSE("content failure for child element"); } return true; } bool testSimilarElementName() { std::string stageContent, stage1Content, stage2Content; CodeDweller::XMLReaderElement reader("elem"); reader .Element("stage", stageContent) .End("stage") .Element("stage1", stage1Content) .End("stage1") .Element("stage2", stage2Content) .End("stage2") .End("elem"); std::string xml; std::string expectedStageContent = "StageContent"; std::string expectedStage1Content = "Stage1Content"; std::string expectedStage2Content = "Stage2Content"; xml = "\n" " " + expectedStage2Content + "\n" " " + expectedStageContent + "\n" " " + expectedStage1Content + "\n" ""; CodeDweller::XMLReaderData confData(xml.data(), xml.size()); reader.initialize(); if (0 == reader.interpret(confData)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if (expectedStageContent != stageContent) { RETURN_FALSE(" content read failure"); } if (expectedStage1Content != stage1Content) { RETURN_FALSE(" content read failure"); } if (expectedStage2Content != stage2Content) { RETURN_FALSE(" content read failure"); } return true; } bool testWrongClosingTag() { std::string stageContent; CodeDweller::XMLReaderElement reader("elem"); reader .Element("stage", stageContent) .End("stage") .End("elem"); std::string xml; std::string expectedStageContent = "StageContent"; xml = "\n" " " + expectedStageContent + "\n" ""; CodeDweller::XMLReaderData confData(xml.data(), xml.size()); reader.initialize(); if (0 != reader.interpret(confData)) { std::cout << "\nParsing '" << xml << "'\n"; RETURN_FALSE("Error: Wrong closing tag not detected."); } return true; } bool testSimilarAttributeName() { std::string nameAttr, naAttr, nameLongAttr; CodeDweller::XMLReaderElement reader("elem"); reader .Element("stage") .Attribute("name", nameAttr) .Attribute("na", naAttr) .Attribute("nameLong", nameLongAttr) .End("stage") .End("elem"); std::string xml; std::string expectedNameAttr = "NameValue"; std::string expectedNaAttr = "NaValue"; std::string expectedNameLongAttr = "NameLongValue"; xml = "\n" " "; CodeDweller::XMLReaderData confData(xml.data(), xml.size()); reader.initialize(); if (0 == reader.interpret(confData)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if (expectedNameAttr != nameAttr) { RETURN_FALSE("\"name\" attribute read failure"); } if (expectedNaAttr != naAttr) { RETURN_FALSE("\"na\" attribute read failure"); } if (expectedNameLongAttr != nameLongAttr) { RETURN_FALSE("\"nameLong\" attribute read failure"); } return true; } bool testInvalidAttribute() { std::string nameAttr; CodeDweller::XMLReaderElement reader("elem"); reader .Element("stage") .Attribute("name", nameAttr) .End("stage") .End("elem"); std::string xml; xml = ""; CodeDweller::XMLReaderData confData(xml.data(), xml.size()); reader.initialize(); if (0 != reader.interpret(confData)) { std::cout << "\nParsing '" << xml << "'\n"; RETURN_FALSE("Error: Invalid attribute not detected."); } return true; } bool testHugeAttributeValue() { std::string xml = ""); CodeDweller::XMLReaderData confData(xml.data(), xml.size()); CodeDweller::XMLReaderElement reader("data"); std::string nameAttr, valueAttr; reader .Attribute("name", nameAttr) .Attribute("value", valueAttr, ">") .End("data"); reader.initialize(); if (0 == reader.interpret(confData)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if ("messageContent" != nameAttr) { RETURN_FALSE("\"name\" attribute read failure"); } if (expectedValue != valueAttr) { RETURN_FALSE("\"value\" attribute read failure"); } return true; } bool testNullAttributeValue() { std::string xml = ""; CodeDweller::XMLReaderData confData(xml.data(), xml.size()); CodeDweller::XMLReaderElement reader("data"); std::string nameAttr, valueAttr, setAttr; reader .Attribute("name", nameAttr) .Attribute("value", valueAttr, ">") .Attribute("set", setAttr, ">") .End("data"); reader.initialize(); if (0 == reader.interpret(confData)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if ("messageContent" != nameAttr) { RETURN_FALSE("\"name\" attribute read failure"); } if ("" != valueAttr) { std::cout << "Expected \"\", got \"" << valueAttr << "\".\n"; RETURN_FALSE("\"value\" attribute read failure"); } if (">" != setAttr) { RETURN_FALSE("\"set\" attribute read failure"); } return true; } bool testIndicator() { std::string xml = ""; CodeDweller::XMLReaderData confData(xml.data(), xml.size()); CodeDweller::XMLReaderElement reader("top"); std::string nameAttr, valueAttr, setAttr; bool foundDataElem; bool foundNameAttr, foundValueAttr, foundSetAttr; reader .Element("data") .indicator(foundDataElem) .Attribute("name", nameAttr).indicator(foundNameAttr) .Attribute("value", valueAttr, ">").indicator(foundValueAttr) .Attribute("set", setAttr, ">").indicator(foundSetAttr) .End("data") .End("top"); reader.initialize(); if (0 == reader.interpret(confData)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if ("messageContent" != nameAttr) { RETURN_FALSE("\"name\" attribute read failure"); } if ("" != valueAttr) { std::cout << "Expected \"\", got \"" << valueAttr << "\".\n"; RETURN_FALSE("\"value\" attribute read failure"); } if (">" != setAttr) { RETURN_FALSE("\"set\" attribute read failure"); } if (!foundDataElem) { RETURN_FALSE("\"XMLReaderElement::indicator\" failure"); } if (!foundNameAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (!foundValueAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (foundSetAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } xml = ""; CodeDweller::XMLReaderData confData1(xml.data(), xml.size()); reader.initialize(); if (0 == reader.interpret(confData1)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if (foundDataElem) { RETURN_FALSE("\"XMLReaderElement::indicator\" failure"); } if (foundNameAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (foundValueAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (foundSetAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } return true; } class TestFunctor : public CodeDweller::AttributeFunctor { public: int numCalled = 0; void operator()(CodeDweller::XMLReaderAttribute& A, CodeDweller::XMLReaderData& D) { numCalled++; } }; bool testIndicatorFunctor() { std::string xml = ""; CodeDweller::XMLReaderData confData(xml.data(), xml.size()); CodeDweller::XMLReaderElement reader("top"); std::string nameAttr, valueAttr, setAttr, fromAttr, toAttr; bool foundDataElem; bool foundNameAttr, foundValueAttr, foundSetAttr, foundFromAttr, foundToAttr; TestFunctor nameFunctor, fromToFunctor; reader .Element("data") .indicator(foundDataElem) .Attribute("name", nameAttr) .indicator(foundNameAttr, nameFunctor) .Attribute("value", valueAttr, ">") .indicator(foundValueAttr) .Attribute("from", fromAttr, ">") .indicator(foundFromAttr, fromToFunctor) .Attribute("to", toAttr, ">") .indicator(foundToAttr, fromToFunctor) .Attribute("set", setAttr, ">") .indicator(foundSetAttr, nameFunctor) .End("data") .End("top"); reader.initialize(); if (0 == reader.interpret(confData)) { RETURN_FALSE("Error parsing XML: " + confData.Log.str()); } if ("messageContent" != nameAttr) { RETURN_FALSE("\"name\" attribute read failure"); } if ("" != valueAttr) { std::cout << "Expected \"\", got \"" << valueAttr << "\".\n"; RETURN_FALSE("\"value\" attribute read failure"); } if ("hello" != fromAttr) { std::cout << "Expected \"hello\", got \"" << fromAttr << "\".\n"; RETURN_FALSE("\"from\" attribute read failure"); } if ("xx" != toAttr) { std::cout << "Expected \"xx\", got \"" << fromAttr << "\".\n"; RETURN_FALSE("\"to\" attribute read failure"); } if (">" != setAttr) { RETURN_FALSE("\"set\" attribute read failure"); } if (!foundDataElem) { RETURN_FALSE("\"XMLReaderElement::indicator\" failure"); } if (!foundNameAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (!foundValueAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (!foundFromAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (!foundToAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (foundSetAttr) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (1 != nameFunctor.numCalled) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } if (2 != fromToFunctor.numCalled) { RETURN_FALSE("\"XMLReaderAttribute::indicator\" failure"); } return true; } //////////////////////////////////////////////////////////////////////////////// // End of tests //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int main() { std::cout << "CodeDweller::XMLReader unit tests" << std::endl << std::endl; RUN_TEST(testEmptyElement); RUN_TEST(testRawData); RUN_TEST(testSimilarElementName); RUN_TEST(testWrongClosingTag); RUN_TEST(testSimilarAttributeName); RUN_TEST(testInvalidAttribute); RUN_TEST(testHugeAttributeValue); RUN_TEST(testNullAttributeValue); RUN_TEST(testIndicator); RUN_TEST(testIndicatorFunctor); SUMMARY; return 0; }