#include "uscxml/config.h" #include "uscxml/Interpreter.h" #include using namespace uscxml; std::set issueLocationsForXML(const std::string xml) { Interpreter interpreter = Interpreter::fromXML(xml); std::list issues = interpreter.validate(); std::set issueLocations; for (std::list::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) { std::cout << *issueIter << std::endl; issueLocations.insert(issueIter->xPath); } return issueLocations; } int main(int argc, char** argv) { google::InitGoogleLogging(argv[0]); google::LogToStderr(); int iterations = 1; while(iterations--) { if (1) { // Unreachable states const char* xml = "" " " " " " " " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"bar\"]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Invalid parents const char* xml = "" " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("/scxml[1]/onentry[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // State has no 'id' attribute const char* xml = "" " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("/scxml[1]/state[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Duplicate state with id const char* xml = "" " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Transition has non-existant target state const char* xml = "" " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Transition can never be optimally enabled (conditionless, eventless) const char* xml = "" " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/transition[2]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Transition can never be optimally enabled (conditionless, more events) const char* xml = "" " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/transition[2]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Initial attribute has invalid target state const char* xml = "" ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("/scxml[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Invoke with unknown type const char* xml = "" " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Send to unknown IO Processor const char* xml = "" " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // SCXML document requires unknown datamodel const char* xml = "" ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("/scxml[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Unknown executable content element const char* xml = "" " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/nonexistant[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Syntax error in script const char* xml = "" " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("/scxml[1]/script[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Syntax error in cond attribute const char* xml = "" " " " " " " " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end()); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/if[1]") != issueLocations.end()); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/if[1]/elseif[1]") != issueLocations.end()); assert(issueLocations.size() == 3); } if (1) { // Syntax error in expr attribute const char* xml = "" " " " " " " " " " " " " " " " " " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/log[1]") != issueLocations.end()); assert(issueLocations.find("//data[@id=\"foo\"]") != issueLocations.end()); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/assign[1]") != issueLocations.end()); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]/content[1]") != issueLocations.end()); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]/param[1]") != issueLocations.end()); assert(issueLocations.size() == 5); } if (1) { // Syntax error with foreach const char* xml = "" " " " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/foreach[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Syntax error with send const char* xml = "" " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Syntax error with invoke const char* xml = "" " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } if (1) { // Syntax error with cancel const char* xml = "" " " " " " " " " " " ""; std::set issueLocations = issueLocationsForXML(xml); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/cancel[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } } return EXIT_SUCCESS; }