Пример #1
0
int main(int argc, char** argv) {
	size_t iterations = 1;

	std::string documentURI;
//	el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Format, "%datetime %level %fbase:%line: %msg");

	if (argc < 2) {
		exit(EXIT_FAILURE);
	}

	int option;
	while ((option = getopt(argc, argv, "n:")) != -1) {
		switch(option) {
		case 'n':
			iterations = strTo<size_t>(optarg);
			break;
		default:
			break;
		}
	}

	documentURI = argv[optind];

	HTTPServer::getInstance(7080, 7443);

	while(iterations--) {
		try {
			Interpreter interpreter = Interpreter::fromURL(documentURI);

//			ActionLanguage al;
//			al.execContent = std::shared_ptr<ContentExecutorImpl>(new ContentExecutorBasic(interpreter.getImpl().get()));
//			interpreter.setActionLanguage(al);

			StateTransitionMonitor mon;
			interpreter.addMonitor(&mon);

			InterpreterState state = InterpreterState::USCXML_UNDEF;
			while(state != USCXML_FINISHED) {
				state = interpreter.step();
			}
			assert(interpreter.isInState("pass"));
		} catch (Event e) {
			std::cerr << "Thrown Event out of Interpreter: " << e;
			return EXIT_FAILURE;
		}
	}

	return 0;
}
Пример #2
0
int main(int argc, char** argv) {
	using namespace uscxml;

	std::set_terminate(customTerminate);

#if defined(HAS_SIGNAL_H) && !defined(WIN32)
	signal(SIGPIPE, SIG_IGN);
#endif

	if (argc < 2) {
		exit(EXIT_FAILURE);
	}

	HTTPServer::getInstance(32954, 32955, NULL); // bind to some random tcp sockets for ioprocessor tests

	google::InitGoogleLogging(argv[0]);
	google::LogToStderr();

//  for (int i = 0; i < argc; i++)
//    std::cout << argv[i] << std::endl;
//  std::cout << optind << std::endl;

	LOG(INFO) << "Processing " << argv[1];
	Interpreter interpreter = Interpreter::fromURI(argv[1]);
	if (interpreter) {
//		interpreter.setCmdLineOptions(argc, argv);
//		interpreter->setCapabilities(Interpreter::CAN_NOTHING);
//		interpreter->setCapabilities(Interpreter::CAN_BASIC_HTTP | Interpreter::CAN_GENERIC_HTTP);

		W3CStatusMonitor* vm = new W3CStatusMonitor();
		interpreter.addMonitor(vm);

//		if (interpreter.getDataModel().getNames().find("ecmascript") != interpreter.getDataModel().getNames().end()) {
//		}

		interpreter.start();
		while(interpreter.runOnMainThread(25));
	}

	return EXIT_SUCCESS;
}
Пример #3
0
int main(int argc, char** argv) {
	using namespace uscxml;

	std::set_terminate(customTerminate);

#if defined(HAS_SIGNAL_H) && !defined(WIN32)
	signal(SIGPIPE, SIG_IGN);
#endif

	if (argc < 2) {
		printUsageAndExit();
	}

	google::InitGoogleLogging(argv[0]);
	google::LogToStderr();

	HTTPServer::getInstance(8088, 8089);
#ifndef _WIN32
	opterr = 0;
#endif
	int option;
	while ((option = getopt(argc, argv, "vl:p:")) != -1) {
		switch(option) {
		case 'l':
			google::InitGoogleLogging(optarg);
			break;
		case 'p':
			uscxml::Factory::setDefaultPluginPath(optarg);
			break;
		case '?':
			break;
		default:
			printUsageAndExit();
			break;
		}
	}

#if 0
	while(true) {
		Interpreter interpreter = Interpreter::fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test235.scxml");
		interpreter.interpret();
	}
#else

	DirectoryWatch* watcher = new DirectoryWatch(argv[optind], true);
	watcher->updateEntries(true);
	std::map<std::string, struct stat> entries = watcher->getAllEntries();

	StatusMonitor vm;

	std::map<std::string, struct stat>::iterator entryIter = entries.begin();
	while(entryIter != entries.end()) {
		if (!boost::ends_with(entryIter->first, ".scxml")) {
			entryIter++;
			continue;
		}

		startedAt = time(NULL);
		lastTransitionAt = time(NULL);

		LOG(INFO) << "Processing " << entryIter->first;
		Interpreter interpreter = Interpreter::fromURL(std::string(argv[optind]) + PATH_SEPERATOR + entryIter->first);
		if (interpreter) {
//			interpreter.setCmdLineOptions(argc, argv);

			interpreter.addMonitor(&vm);

			interpreter.start();
			int now = time(NULL);
			while(now - startedAt < 20 && now - lastTransitionAt < 2) {
				// let the interpreter run for a bit
				tthread::this_thread::sleep_for(tthread::chrono::seconds(1));
				now = time(NULL);
			}

		}
		entryIter++;
	}

	delete watcher;
#endif
	return EXIT_SUCCESS;
}
Пример #4
0
int main(int argc, char** argv) {

	google::InitGoogleLogging(argv[0]);
	google::LogToStderr();

	int iterations = 1;

	while(iterations--) {

		if (1) {
			// Potential endless loop

			const char* xml =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<datamodel><data id=\"counter\" expr=\"5\" /></datamodel>"
			    "	<state id=\"foo\">"
			    "		<onentry><script>counter--;</script></onentry>"
			    "		<transition target=\"foo\" cond=\"counter > 0\" />"
			    "		<transition target=\"bar\" cond=\"counter == 0\" />"
			    " </state>"
			    "	<state id=\"bar\" final=\"true\" />"
			    "</scxml>";

			IssueMonitor monitor;
			Interpreter interpreter = Interpreter::fromXML(xml, "");
			interpreter.addMonitor(&monitor);
			interpreter.interpret();

			// first reiteration is not counted as it might be valid when raising internal errors
			assert(runtimeIssues == 3);
		}

		if (1) {
			// Unreachable states 1

			const char* xml =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"foo\">"
			    "		<parallel id=\"foz\">"
			    "			<state id=\"s0\" />"
			    "			<state id=\"s1\" />"
			    "			<state id=\"s2\" />"
			    "		</parallel>"
			    " </state>"
			    "	<state id=\"bar\" />"
			    "</scxml>";

			std::set<std::string> issueLocations = issueLocationsForXML(xml);
			assert(issueLocations.find("//state[@id=\"bar\"]") != issueLocations.end());
			assert(issueLocations.size() == 1);
		}

		if (1) {
			// Invalid parents
			const char* xml =
			    "<scxml datamodel=\"ecmascript\">"
			    "		<onentry>"
			    "			<cancel sendidexpr=\"foo\" />"
			    "		</onentry>"
			    "</scxml>";

			std::set<std::string> issueLocations = issueLocationsForXML(xml);
			assert(issueLocations.find("/scxml[1]/onentry[1]") != issueLocations.end());
			assert(issueLocations.size() == 1);
		}

		if (0) {
			// State has no 'id' attribute
            // *** This is not actually an error! ***
			const char* xml =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state>"
			    "		<transition/>"
			    " </state>"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\" />"
			    " <state id=\"start\" />"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<transition target=\"done\" />"
			    " </state>"
			    "</scxml>";

			std::set<std::string> issueLocations = issueLocationsForXML(xml);
			assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end());
			assert(issueLocations.size() == 1);
		}

        if (1) {
            // Useless history 1
            
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\" initial=\"bar\">"
            "   <history id=\"bar\" />"
            "   <state id=\"baz\" />"
            "   <transition event=\"e.foo\" target=\"done\" />"
            "   <transition event=\"e.bar\" target=\"baz\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

        if (1) {
            // Useless history 2
            
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\" initial=\"bar\">"
            "   <history id=\"bar\">"
            "       <transition target=\"foo\" />"
            "   </history>"
            "   <transition target=\"done\" />"
            "	<state id=\"foo\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

        if (1) {
            // No legal completion
            
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\" initial=\"foo bar\">"
            "	<state id=\"foo\" />"
            "	<state id=\"bar\" />"
            "   <transition target=\"foo bar\" />"
            " </state>"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
            assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end());
            assert(issueLocations.size() == 2);
        }

        if (1) {
            // attribute constraints
            
            {
                // initial attribute and <initial> child
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\" initial=\"foo\">"
                "   <initial>"
                "       <transition target=\"foo\" />"
                "   </initial>"
                "	<state id=\"foo\" />"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
                assert(issueLocations.size() == 1);
            }
            
            {
                // initial attribute with atomic state
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\" initial=\"\" />"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
                assert(issueLocations.size() == 1);
            }
            
            {
                // initial child with atomic state
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\">"
                "   <initial>"
                "       <transition target=\"start\" />"
                "   </initial>"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
                assert(issueLocations.size() == 2); // also invalid non-child target state in initial
            }

            // combinations of namelist, content and param
            {
                // send with content and namelist, not allowed
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\">"
                "   <onentry>"
                "     <send target=\"#_external\" namelist=\"var1\">"
                "       <content>Foo!</content>"
                "     </send>"
                "   </onentry>"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end());
                assert(issueLocations.size() == 1);
            }

            {
                // send with content and params, not allowed
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\">"
                "   <onentry>"
                "     <send target=\"#_external\">"
                "       <param name=\"foo\" expr=\"3\" />"
                "       <content>Foo!</content>"
                "     </send>"
                "   </onentry>"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end());
                assert(issueLocations.size() == 1);
            }

            {
                // send with params and namelist, perfectly acceptable
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\">"
                "   <onentry>"
                "     <send target=\"#_external\" namelist=\"foo\">"
                "       <param name=\"foo\" expr=\"3\" />"
                "     </send>"
                "   </onentry>"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.size() == 0);
            }
            
            {
                // invoke with content and src, not allowed
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\">"
                "     <invoke type=\"scxml\" src=\"var1\">"
                "       <content>Foo!</content>"
                "     </invoke>"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end());
                assert(issueLocations.size() == 1);
            }

            {
                // invoke with namelist and param, not allowed
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\">"
                "     <invoke type=\"scxml\" namelist=\"var1\">"
                "       <param name=\"foo\" expr=\"3\" />"
                "     </invoke>"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end());
                assert(issueLocations.size() == 1);
            }

            {
                // invoke with param and content, perfectly acceptable
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\">"
                "     <invoke type=\"scxml\">"
                "       <param name=\"foo\" expr=\"3\" />"
                "       <content>Foo!</content>"
                "     </invoke>"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.size() == 0);
            }

            {
                // invoke with namelist and content, perfectly acceptable
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\">"
                "     <invoke type=\"scxml\" namelist=\"var1\">"
                "       <content>Foo!</content>"
                "     </invoke>"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.size() == 0);
            }
            
            {
                // donedata with content and param, not allowed
                const char* xml =
                "<scxml datamodel=\"ecmascript\">"
                " <state id=\"start\">"
                "     <donedata>"
                "       <param name=\"foo\" expr=\"3\" />"
                "       <content>Foo!</content>"
                "     </donedata>"
                " </state>"
                "</scxml>";
                
                std::set<std::string> issueLocations = issueLocationsForXML(xml);
                assert(issueLocations.find("//state[@id=\"start\"]/donedata[1]") != issueLocations.end());
                assert(issueLocations.size() == 1);
            }


        }
    
    
		if (1) {
			// Transition can never be optimally enabled (conditionless, eventless)

			const char* xml =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<transition target=\"done\" />"
			    "		<transition target=\"done\" />"
			    " </state>"
			    " <final id=\"done\" />"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<transition event=\"error\" target=\"done\" />"
			    "		<transition event=\"error.bar error.foo\" />"
			    " </state>"
			    " <final id=\"done\" />"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\" initial=\"foo\">"
			    "</scxml>";

			std::set<std::string> issueLocations = issueLocationsForXML(xml);
			assert(issueLocations.find("/scxml[1]") != issueLocations.end());
			assert(issueLocations.size() == 1);
		}

        if (1) {
            // Initial attribute with target outside of children
            
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\" initial=\"foo done\">"
            "	<state id=\"foo\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

        if (1) {
            // Initial transition with target outside of children
            
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\">"
            "   <initial>"
            "       <transition target=\"foo done\" />"
            "   </initial>"
            "	<state id=\"foo\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

        if (1) {
            // Initial history transition with target outside of children
            
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\" initial=\"bar\">"
            "   <history id=\"bar\">"
            "       <transition target=\"foo done\" />"
            "   </history>"
            "	<state id=\"foo\">"
            "       <transition target=\"baz\" />"
            "   </state>"
            "	<state id=\"baz\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

        if (1) {
            // Initial transition with target outside of children
            
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\">"
            "   <initial>"
            "       <transition target=\"foo done\" />"
            "   </initial>"
            "	<state id=\"foo\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

		if (1) {
			// Initial transition with event
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\">"
            "   <initial>"
            "       <transition event=\"e.foo\" target=\"foo\" />"
            "   </initial>"
            "	<state id=\"foo\" />"
            "   <transition event=\"e.bar\" target=\"done\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";

			std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end());
			assert(issueLocations.size() == 1);
		}

        if (1) {
            // Initial transition with condition
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\">"
            "   <initial>"
            "       <transition cond=\"true\" target=\"foo\" />"
            "   </initial>"
            "	<state id=\"foo\" />"
            "   <transition event=\"e.bar\" target=\"done\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

        if (1) {
            // Initial with multiple transitions
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\">"
            "   <initial>"
            "       <transition target=\"foo\" />"
            "       <transition target=\"foo\" />"
            "   </initial>"
            "	<state id=\"foo\" />"
            "   <transition event=\"e.bar\" target=\"done\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

        if (1) {
            // Initial with no transitions
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\">"
            "   <initial />"
            "	<state id=\"foo\" />"
            "   <transition event=\"e.bar\" target=\"done\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

        if (1) {
            // History transition with event
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\" initial=\"bar\">"
            "   <history id=\"bar\">"
            "       <transition event=\"e.foo\" target=\"foo\" />"
            "   </history>"
            "	<state id=\"foo\">"
            "       <state id=\"foo.s1\">"
            "           <transition target=\"foo.s2\" />"
            "       </state>"
            "       <state id=\"foo.s2\" />"
            "   </state>"
            "   <transition event=\"e.bar\" target=\"done\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

        if (1) {
            // History transition with condition
            const char* xml =
            "<scxml datamodel=\"ecmascript\">"
            " <state id=\"start\" initial=\"bar\">"
            "   <history id=\"bar\">"
            "       <transition cond=\"false\" target=\"foo\" />"
            "   </history>"
            "	<state id=\"foo\">"
            "       <state id=\"foo.s1\">"
            "           <transition target=\"foo.s2\" />"
            "       </state>"
            "       <state id=\"foo.s2\" />"
            "   </state>"
            "   <transition event=\"e.bar\" target=\"done\" />"
            " </state>"
            " <final id=\"done\" />"
            "</scxml>";
            
            std::set<std::string> issueLocations = issueLocationsForXML(xml);
            assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end());
            assert(issueLocations.size() == 1);
        }

		if (1) {
			// Send to unknown IO Processor

			const char* xml =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<onentry>"
			    "			<send type=\"non-existant\" />"
			    "		</onentry>"
			    " </state>"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"non-existant\">"
			    "</scxml>";

			std::set<std::string> issueLocations = issueLocationsForXML(xml);
			assert(issueLocations.find("/scxml[1]") != issueLocations.end());
			assert(issueLocations.size() == 1);
		}

		if (1) {
			// Unknown executable content element

			const char* xml =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<onentry>"
			    "			<nonexistant />"
			    "		</onentry>"
			    " </state>"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<script>"
			    "   $wfwegr^ "
			    " </script>"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<onentry>"
			    "			<if cond=\"%2345\">"
			    "			<elseif cond=\"%2345\" />"
			    "			</if>"
			    "		</onentry>"
			    "		<transition cond=\"%2345\" />"
			    " </state>"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<datamodel>"
			    "		<data id=\"foo\" expr=\"%2345\" />"
			    "	</datamodel>"
			    "	<state id=\"start\">"
			    "		<onentry>"
			    "			<log expr=\"%2345\" />"
			    "			<assign location=\"foo\" expr=\"%2345\" />"
			    "			<send>"
			    "				<param expr=\"%2345\" />"
			    "			</send>"
                "			<send>"
                "				<content expr=\"%2345\" />"
                "			</send>"
			    "		</onentry>"
			    " </state>"
			    "</scxml>";

			std::set<std::string> 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]/param[1]") != issueLocations.end());
            assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[2]/content[1]") != issueLocations.end());
			assert(issueLocations.size() == 5);
		}

		if (1) {
			// Syntax error with foreach

			const char* xml =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<onentry>"
			    "			<foreach item=\"%2345\" index=\"%2345\" array=\"%2345\">"
			    "			</foreach>"
			    "		</onentry>"
			    " </state>"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<onentry>"
			    "			<send eventexpr=\"%2345\" targetexpr=\"%2345\" typeexpr=\"%2345\" idlocation=\"%2345\" delayexpr=\"%2345\" />"
			    "		</onentry>"
			    " </state>"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<invoke typeexpr=\"%2345\" srcexpr=\"%2345\" idlocation=\"%2345\" />"
			    " </state>"
			    "</scxml>";

			std::set<std::string> 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 =
			    "<scxml datamodel=\"ecmascript\">"
			    "	<state id=\"start\">"
			    "		<onentry>"
			    "			<cancel sendidexpr=\"%2345\" />"
			    "		</onentry>"
			    " </state>"
			    "</scxml>";

			std::set<std::string> issueLocations = issueLocationsForXML(xml);
			assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/cancel[1]") != issueLocations.end());
			assert(issueLocations.size() == 1);
		}


	}

	return EXIT_SUCCESS;
}