|
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
|
|
#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 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 =
|
|
|
|
|
|
"<elem>\n"
|
|
|
|
|
|
" <stage2>" + expectedStage2Content + "</stage2>\n"
|
|
|
|
|
|
" <stage>" + expectedStageContent + "</stage>\n"
|
|
|
|
|
|
" <stage1>" + expectedStage1Content + "</stage1>\n"
|
|
|
|
|
|
"</elem>";
|
|
|
|
|
|
|
|
|
|
|
|
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("<stage> content read failure");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (expectedStage1Content != stage1Content) {
|
|
|
|
|
|
RETURN_FALSE("<stage1> content read failure");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (expectedStage2Content != stage2Content) {
|
|
|
|
|
|
RETURN_FALSE("<stage2> content read failure");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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 =
|
|
|
|
|
|
"<elem>\n"
|
|
|
|
|
|
" <stage\n"
|
|
|
|
|
|
" name='" + expectedNameAttr + "'\n"
|
|
|
|
|
|
" na='" + expectedNaAttr + "'\n"
|
|
|
|
|
|
" nameLong='" + expectedNameLongAttr + "'\n"
|
|
|
|
|
|
"/></elem>";
|
|
|
|
|
|
|
|
|
|
|
|
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 testNullAttributeValue() {
|
|
|
|
|
|
|
|
|
|
|
|
std::string xml = "<data name='messageContent' value=''/>";
|
|
|
|
|
|
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 = "<top><data name='messageContent' value=''/></top>";
|
|
|
|
|
|
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 = "<top><data1 name='messageContent' value=''/></top>";
|
|
|
|
|
|
|
|
|
|
|
|
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 =
|
|
|
|
|
|
"<top><data name='messageContent' value='' from='hello' "
|
|
|
|
|
|
"to='xx'/></top>";
|
|
|
|
|
|
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(testSimilarElementName);
|
|
|
|
|
|
RUN_TEST(testSimilarAttributeName);
|
|
|
|
|
|
RUN_TEST(testNullAttributeValue);
|
|
|
|
|
|
RUN_TEST(testIndicator);
|
|
|
|
|
|
|
|
|
|
|
|
SUMMARY;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|