diff options
author | Stefan Radomski <github@mintwerk.de> | 2017-01-27 21:54:43 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2017-01-27 21:54:43 (GMT) |
commit | 7f83038a1ef642b883417cc984d1f8ca9f0bc64b (patch) | |
tree | fd9236e866a06b250992e84bbf41324adf93a9fd /test | |
parent | b450411ee8f0a57f3ec3909d65ecc289189e2b35 (diff) | |
download | uscxml-7f83038a1ef642b883417cc984d1f8ca9f0bc64b.zip uscxml-7f83038a1ef642b883417cc984d1f8ca9f0bc64b.tar.gz uscxml-7f83038a1ef642b883417cc984d1f8ca9f0bc64b.tar.bz2 |
Reactivated BUILD_AS_PLUGINS
Diffstat (limited to 'test')
-rw-r--r-- | test/CMakeLists.txt | 40 | ||||
-rw-r--r-- | test/ctest/scripts/test_generated_c.cmake | 31 | ||||
-rw-r--r-- | test/src/test-gen-c.cpp | 4 | ||||
-rw-r--r-- | test/src/test-utils.cpp | 74 | ||||
-rw-r--r-- | test/src/test-validating.cpp | 1323 |
5 files changed, 806 insertions, 666 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bc1c85a..2b90b97 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -39,25 +39,32 @@ function(USCXML_TEST_COMPILE) add_test(${USCXML_TEST_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${USCXML_TEST_NAME} ${USCXML_TEST_ARGS}) set_property(TEST ${USCXML_TEST_NAME} PROPERTY LABELS ${USCXML_TEST_LABEL}) set_property(TEST ${USCXML_TEST_NAME} PROPERTY TIMEOUT ${TEST_TIMEOUT}) + set_property(TEST ${USCXML_TEST_NAME} PROPERTY ENVIRONMENT "USCXML_PLUGIN_PATH=${CMAKE_BINARY_DIR}/lib/plugins") endif () set_target_properties(${USCXML_TEST_NAME} PROPERTIES FOLDER "Tests") endfunction() # simple one file tests +USCXML_TEST_COMPILE(NAME test-utils LABEL general/test-utils FILES src/test-utils.cpp) USCXML_TEST_COMPILE(NAME test-extensions LABEL general/test-extensions FILES src/test-extensions.cpp ../contrib/src/uscxml/PausableDelayedEventQueue.cpp) USCXML_TEST_COMPILE(NAME test-url LABEL general/test-url FILES src/test-url.cpp) USCXML_TEST_COMPILE(NAME test-lifecycle LABEL general/test-lifecycle FILES src/test-lifecycle.cpp) USCXML_TEST_COMPILE(NAME test-validating LABEL general/test-validating FILES src/test-validating.cpp) USCXML_TEST_COMPILE(NAME test-snippets LABEL general/test-snippets FILES src/test-snippets.cpp) -USCXML_TEST_COMPILE( - NAME test-serialization - LABEL general/test-serialization - FILES src/test-serialization.cpp ../contrib/src/uscxml/PausableDelayedEventQueue.cpp - ARGS ${CMAKE_CURRENT_SOURCE_DIR}/w3c/ecma) + +if (NOT BUILD_AS_PLUGINS) + USCXML_TEST_COMPILE( + NAME test-serialization + LABEL general/test-serialization + FILES src/test-serialization.cpp ../contrib/src/uscxml/PausableDelayedEventQueue.cpp + ARGS ${CMAKE_CURRENT_SOURCE_DIR}/w3c/ecma) +endif() # USCXML_TEST_COMPILE(NAME test-c89-parser LABEL general/test-c89-parser FILES src/test-c89-parser.cpp) # test-stress is not an automated test -USCXML_TEST_COMPILE(BUILD_ONLY NAME test-stress LABEL general/test-stress FILES src/test-stress.cpp) +if (NOT BUILD_AS_PLUGINS) + USCXML_TEST_COMPILE(BUILD_ONLY NAME test-stress LABEL general/test-stress FILES src/test-stress.cpp) +endif() file(GLOB_RECURSE USCXML_WRAPPERS ${PROJECT_SOURCE_DIR}/src/bindings/swig/wrapped/*.cpp @@ -91,6 +98,7 @@ foreach (USCXML_ISSUE ${USCXML_ISSUES}) if (ISSUE_TYPE STREQUAL ".scxml") add_test(issue/${ISSUE_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-state-pass ${USCXML_ISSUE}) set_property(TEST issue/${ISSUE_NAME} PROPERTY LABELS issue/${ISSUE_NAME}) + set_property(TEST issue/${ISSUE_NAME} PROPERTY ENVIRONMENT "USCXML_PLUGIN_PATH=${CMAKE_BINARY_DIR}/lib/plugins") else () USCXML_TEST_COMPILE(NAME ${ISSUE_NAME} LABEL issues/${ISSUE_NAME} FILES ${USCXML_ISSUE}) endif () @@ -130,6 +138,7 @@ foreach (USCXML_HEADER ${USCXML_PUBLIC_HEADERS}) -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} -P ${CMAKE_CURRENT_SOURCE_DIR}/ctest/scripts/run_header_compiles.cmake) set_property(TEST "header/${USCXML_REL_HEADER}" PROPERTY LABELS "header/${USCXML_REL_HEADER}") + set_property(TEST "header/${USCXML_REL_HEADER}" PROPERTY ENVIRONMENT "USCXML_PLUGIN_PATH=${CMAKE_BINARY_DIR}/lib/plugins") endforeach () @@ -142,7 +151,8 @@ if (PERL_BIN) WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test/src ) set_property(TEST "general/test-debug-api" PROPERTY LABELS "general/test-debug-api") - set_tests_properties("general/test-debug-api" PROPERTIES DEPENDS uscxml-browser) + set_property(TEST "general/test-debug-api" PROPERTY DEPENDS uscxml-browser) + set_property(TEST "general/test-debug-api" PROPERTY ENVIRONMENT "USCXML_PLUGIN_PATH=${CMAKE_BINARY_DIR}/lib/plugins") endif () @@ -299,7 +309,7 @@ if (NOT BUILD_MINIMAL) -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} -DSCAFFOLDING_FOR_GENERATED_C:FILEPATH=${CMAKE_CURRENT_SOURCE_DIR}/src/test-gen-c.cpp -P ${CMAKE_CURRENT_SOURCE_DIR}/ctest/scripts/test_generated_${TEST_TARGET}.cmake) - set_tests_properties("${TEST_NAME}" PROPERTIES DEPENDS uscxml-transform) + set_property(TEST ${TEST_NAME} PROPERTY DEPENDS uscxml-transform) set(TEST_ADDED ON) endif() @@ -313,7 +323,7 @@ if (NOT BUILD_MINIMAL) -Dtest.file=${W3C_TEST} -Duscxml.jar=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/uscxml.jar WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/contrib/java/bindings) - set_tests_properties("${TEST_NAME}" PROPERTIES DEPENDS jar) + set_property(TEST ${TEST_NAME} PROPERTY DEPENDS jar) set(TEST_ADDED ON) endif () @@ -325,7 +335,8 @@ if (NOT BUILD_MINIMAL) ${W3C_TEST} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/contrib/python/bindings) - set_tests_properties("${TEST_NAME}" PROPERTIES ENVIRONMENT "USCXML_PYTHON_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") + set_property(TEST ${TEST_NAME} PROPERTY ENVIRONMENT "USCXML_PYTHON_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") + set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT "USCXML_PLUGIN_PATH=${CMAKE_BINARY_DIR}/lib/plugins") set(TEST_ADDED ON) endif () @@ -343,8 +354,8 @@ if (NOT BUILD_MINIMAL) -DSPIN_BIN:FILEPATH=${SPIN_BIN} -DCC_BIN:FILEPATH=${CC_BIN} -P ${CMAKE_CURRENT_SOURCE_DIR}/ctest/scripts/run_promela_test.cmake) - set_tests_properties("${TEST_NAME}" PROPERTIES PASS_REGULAR_EXPRESSION "depth reached [0-9]+, errors: 0") - set_tests_properties("${TEST_NAME}" PROPERTIES FAIL_REGULAR_EXPRESSION "depth reached [0-9]+, errors: [1-9]+") + set_property(TEST ${TEST_NAME} PROPERTY PASS_REGULAR_EXPRESSION "depth reached [0-9]+, errors: 0") + set_property(TEST ${TEST_NAME} PROPERTY FAIL_REGULAR_EXPRESSION "depth reached [0-9]+, errors: [1-9]+") set(TEST_ADDED ON) elseif (TEST_TYPE MATCHES "^fsm.*") @@ -356,9 +367,10 @@ if (NOT BUILD_MINIMAL) if (TEST_ADDED) set_property(TEST ${TEST_NAME} PROPERTY LABELS ${TEST_NAME}) - set_tests_properties(${TEST_NAME} PROPERTIES TIMEOUT ${TEST_TIMEOUT}) + set_property(TEST ${TEST_NAME} PROPERTY TIMEOUT ${TEST_TIMEOUT}) + set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT "USCXML_PLUGIN_PATH=${CMAKE_BINARY_DIR}/lib/plugins") if (IS_PERFORMANCE_TEST) - set_tests_properties("${TEST_NAME}" PROPERTIES ENVIRONMENT USCXML_BENCHMARK_ITERATIONS=${TEST_BENCHMARK_ITERATIONS}) + set_property(TEST ${TEST_NAME} APPEND PROPERTY ENVIRONMENT USCXML_BENCHMARK_ITERATIONS=${TEST_BENCHMARK_ITERATIONS}) endif () endif () diff --git a/test/ctest/scripts/test_generated_c.cmake b/test/ctest/scripts/test_generated_c.cmake index c170639..b130d29 100644 --- a/test/ctest/scripts/test_generated_c.cmake +++ b/test/ctest/scripts/test_generated_c.cmake @@ -15,36 +15,6 @@ if (CMD_RESULT) endif () message(STATUS "time for transforming to c machine") -# set(COMPILE_CMD_OBJ -# "-c" "${OUTDIR}/${TEST_FILE_NAME}.machine.c" -# "-o" "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" -# "-Ofast" "-ansi" "-m16") -# -# message(STATUS "${CC_BIN} ${COMPILE_CMD_OBJ}") -# execute_process( -# COMMAND time -p ${CC_BIN} ${COMPILE_CMD_OBJ} -# WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) -# if(CMD_RESULT) -# message(FATAL_ERROR "Error running gcc ${CC_BIN}: ${CMD_RESULT}") -# endif() -# file (SIZE "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" BINARY_SIZE) -# message("Size of compiled unit optimized for speed: ${BINARY_SIZE}") -# -# set(COMPILE_CMD_OBJ -# "-c" "${OUTDIR}/${TEST_FILE_NAME}.machine.c" -# "-o" "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" -# "-Os" "-ansi" "-m16") -# -# message(STATUS "${CC_BIN} ${COMPILE_CMD_OBJ}") -# execute_process( -# COMMAND time -p ${CC_BIN} ${COMPILE_CMD_OBJ} -# WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) -# if(CMD_RESULT) -# message(FATAL_ERROR "Error running gcc ${CC_BIN}: ${CMD_RESULT}") -# endif() -# file (SIZE "${OUTDIR}/${TEST_FILE_NAME}.machine.c.o" BINARY_SIZE) -# message("Size of compiled unit optimized for size: ${BINARY_SIZE}") - set(COMPILE_CMD_BIN "-O0" "-std=c++11" @@ -53,6 +23,7 @@ set(COMPILE_CMD_BIN "-o" "${OUTDIR}/${TEST_FILE_NAME}" "-L${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" "-L${PROJECT_BINARY_DIR}/deps/xerces-c/lib" + "-L/opt/local/lib" "-luscxml" "-lxerces-c" "-include" "${OUTDIR}/${TEST_FILE_NAME}.machine.c" diff --git a/test/src/test-gen-c.cpp b/test/src/test-gen-c.cpp index 090b289..7af121c 100644 --- a/test/src/test-gen-c.cpp +++ b/test/src/test-gen-c.cpp @@ -18,9 +18,7 @@ #ifndef AUTOINCLUDE_TEST #include "test-c-machine.scxml.c" -//#include "/Users/sradomski/Documents/TK/Code/uscxml/build/cli/test/gen/c/ecma/test562.scxml.machine.c" -//#include "/Users/sradomski/Documents/TK/Code/uscxml/build/cli/test/gen/c/ecma/test558.scxml.machine.c" -// #include "/Users/sradomski/Documents/TK/Code/uscxml/build/cli/test/gen/c/lua/test530.scxml.machine.c" +//#include "/Users/sradomski/Documents/TK/Code/uscxml/build/cli/test/gen/c/ecma/test446.scxml.machine.c" #endif #include "uscxml/util/URL.h" diff --git a/test/src/test-utils.cpp b/test/src/test-utils.cpp new file mode 100644 index 0000000..474cf89 --- /dev/null +++ b/test/src/test-utils.cpp @@ -0,0 +1,74 @@ +/** + * This file contains all the snippets in the doxygen documentation. + * + * It is not actually a test as such, but makes sure that the snippets will + * actually compile and do what we claim they do. + */ +#define protected public + +#include "uscxml/config.h" +#include "uscxml/Common.h" +#include "uscxml/Interpreter.h" +#include "uscxml/interpreter/InterpreterImpl.h" +#include "uscxml/util/DOM.h" + +using namespace uscxml; +using namespace XERCESC_NS; + +void testDOMUtils() { + + const char* xml = + "<scxml>" + " <state doc=\"1\" post=\"1\">" + " <transition doc=\"1\" post=\"1\" />" + " </state>" + " <state doc=\"2\" post=\"3\">" + " <transition doc=\"2\" post=\"3\" />" + " <state doc=\"3\" post=\"2\">" + " <transition doc=\"2\" post=\"2\" />" + " </state>" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + size_t index = 1; + + Interpreter interpreter = Interpreter::fromXML(xml, ""); + interpreter.step(); + XERCESC_NS::DOMElement* scxml = interpreter.getImpl()->_scxml; + + { + // postfix + std::list<DOMElement*> result; + DOMUtils::filterElementGeneric({ "state" }, result, scxml, DOMUtils::POSTFIX, true, true); + index = 1; + for (auto trans : result) { + assert(HAS_ATTR(trans, "post")); + std::cout << "post: " << ATTR(trans, "post") << std::endl; + assert(ATTR(trans, "post") == toStr(index)); + index++; + } + } + + { + // document + std::list<DOMElement*> result; + DOMUtils::filterElementGeneric({ "state" }, result, scxml, DOMUtils::DOCUMENT, true, true); + index = 1; + for (auto trans : result) { + assert(HAS_ATTR(trans, "doc")); + std::cout << "doc: " << ATTR(trans, "doc") << std::endl; + assert(ATTR(trans, "doc") == toStr(index)); + index++; + } + } + +} + +int main(int argc, char** argv) { + try { + testDOMUtils(); + } catch (ErrorEvent e) { + std::cout << e; + } +} diff --git a/test/src/test-validating.cpp b/test/src/test-validating.cpp index fa660b9..7e0cc31 100644 --- a/test/src/test-validating.cpp +++ b/test/src/test-validating.cpp @@ -5,6 +5,8 @@ #include "uscxml/interpreter/Logging.h" #include <xercesc/util/PlatformUtils.hpp> +uscxml::Factory* factory = NULL; + using namespace uscxml; std::set<std::string> issueLocationsForXML(const std::string xml) { @@ -36,782 +38,865 @@ public: } }; -int main(int argc, char** argv) { - - using namespace XERCESC_NS; - - int iterations = 1; +bool endlessLoop() { - while(iterations--) { - - if (Factory::getInstance()->hasDataModel("ecmascript")) { - // 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>"; + if (Factory::getInstance()->hasDataModel("ecmascript")) { + // Potential endless loop - IssueMonitor monitor; - Interpreter interpreter = Interpreter::fromXML(xml, ""); - interpreter.addMonitor(&monitor); + 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>"; - while(interpreter.step() > 0) {} + IssueMonitor monitor; + Interpreter interpreter = Interpreter::fromXML(xml, ""); + interpreter.addMonitor(&monitor); - // four identical configurations between macrosteps - assert(runtimeIssues == 4); - } + while(interpreter.step() > 0) {} - if (1) { - // Unreachable states 1 + // four identical configurations between macrosteps + assert(runtimeIssues == 4); + } + return true; +} - const char* xml = - "<scxml>" - " <state id=\"foo\">" - " <parallel id=\"foz\">" - " <state id=\"s0\" />" - " <state id=\"s1\" />" - " <state id=\"s2\" />" - " </parallel>" - " </state>" - " <state id=\"bar\" />" - "</scxml>"; +bool unreachableState() { + if (1) { + // Unreachable states 1 + + const char* xml = + "<scxml>" + " <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); + } + return true; +} - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"bar\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } +bool invalidParents() { + if (1) { + // Invalid parents + const char* xml = + "<scxml>" + " <onentry>" + " <cancel sendid=\"foo\" />" + " </onentry>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("/scxml[1]/onentry[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + return true; +} - if (1) { - // Invalid parents - const char* xml = - "<scxml>" - " <onentry>" - " <cancel sendid=\"foo\" />" - " </onentry>" - "</scxml>"; +bool noIdAttr() { + if (1) { + // State has no 'id' attribute + // *** This is not actually an error! *** + const char* xml = + "<scxml>" + " <state>" + " <transition/>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("/scxml[1]/state[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("/scxml[1]/onentry[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + return true; +} - if (1) { - // State has no 'id' attribute - // *** This is not actually an error! *** - const char* xml = - "<scxml>" - " <state>" - " <transition/>" - " </state>" - "</scxml>"; +bool duplicateIdAttr() { + if (1) { + // Duplicate state with id + const char* xml = + "<scxml>" + " <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); + } - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("/scxml[1]/state[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + return true; +} - if (1) { - // Duplicate state with id - const char* xml = - "<scxml>" - " <state id=\"start\" />" - " <state id=\"start\" />" - "</scxml>"; +bool invalidTarget() { + if (1) { + // Transition has non-existant target state - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + const char* xml = + "<scxml>" + " <state id=\"start\">" + " <transition target=\"done\" />" + " </state>" + "</scxml>"; - if (1) { - // Transition has non-existant target state + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } - const char* xml = - "<scxml>" - " <state id=\"start\">" - " <transition target=\"done\" />" - " </state>" - "</scxml>"; + return true; +} - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } +bool uselessHistory1() { + if (1) { + // Useless history 1 + + const char* xml = + "<scxml>" + " <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 1 + return true; +} - const char* xml = - "<scxml>" - " <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>"; +bool uselessHistory2() { + if (1) { + // Useless history 2 + + const char* xml = + "<scxml>" + " <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); + } + return true; +} - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } +bool illegalCompletion() { + if (1) { + // No legal completion + + const char* xml = + "<scxml>" + " <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); + } + return true; +} - if (1) { - // Useless history 2 +bool attributeConstraints() { + if (1) { + // attribute constraints + { + // initial attribute and <initial> child const char* xml = "<scxml>" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" + " <state id=\"start\" initial=\"foo\">" + " <initial>" " <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>" - " <state id=\"start\" initial=\"foo bar\">" + " </initial>" " <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>" - " <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>" - " <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>" - " <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>" - " <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>" - " <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>" - " <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>" - " <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>" - " <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>" - " <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>" - " <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>" - " <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>" - " <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>" - " <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 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 - + { + // initial attribute with atomic state const char* xml = "<scxml>" - " <state id=\"start\" initial=\"foo done\">" - " <state id=\"foo\" />" - " </state>" - " <final id=\"done\" />" + " <state id=\"start\" initial=\"\" />" "</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 + { + // initial child with atomic state const char* xml = "<scxml>" " <state id=\"start\">" " <initial>" - " <transition target=\"foo done\" />" + " <transition target=\"start\" />" " </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); // there are actually two issues with the transition + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.size() == 2); // also invalid non-child target state in initial } - if (1) { - // Initial history transition with target outside of children + // combinations of namelist, content and param + { + // send with content and namelist, not allowed const char* xml = "<scxml>" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" - " <transition target=\"foo done\" />" - " </history>" - " <state id=\"foo\">" - " <transition target=\"baz\" />" - " </state>" - " <state id=\"baz\" />" + " <state id=\"start\">" + " <onentry>" + " <send target=\"#_external\" namelist=\"var1\">" + " <content>Foo!</content>" + " </send>" + " </onentry>" " </state>" - " <final id=\"done\" />" "</scxml>"; std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } - if (1) { - // Initial transition with target outside of children + { + // send with content and params, not allowed const char* xml = "<scxml>" " <state id=\"start\">" - " <initial>" - " <transition target=\"foo done\" />" - " </initial>" - " <state id=\"foo\" />" + " <onentry>" + " <send target=\"#_external\">" + " <param name=\"foo\" expr=\"3\" />" + " <content>Foo!</content>" + " </send>" + " </onentry>" " </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.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } - if (1) { - // Initial transition with event + { + // send with params and namelist, perfectly acceptable const char* xml = "<scxml>" " <state id=\"start\">" - " <initial>" - " <transition event=\"e.foo\" target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" + " <onentry>" + " <send target=\"#_external\" namelist=\"foo\">" + " <param name=\"foo\" expr=\"3\" />" + " </send>" + " </onentry>" " </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); + assert(issueLocations.size() == 0); } - if (1) { - // Initial transition with condition + { + // invoke with content and src, not allowed const char* xml = "<scxml>" " <state id=\"start\">" - " <initial>" - " <transition cond=\"true\" target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" + " <invoke type=\"scxml\" src=\"var1\">" + " <content>Foo!</content>" + " </invoke>" " </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.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } - if (1) { - // Initial with multiple transitions + { + // invoke with namelist and param, not allowed const char* xml = "<scxml>" " <state id=\"start\">" - " <initial>" - " <transition target=\"foo\" />" - " <transition target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" + " <invoke type=\"scxml\" namelist=\"var1\">" + " <param name=\"foo\" expr=\"3\" />" + " </invoke>" " </state>" - " <final id=\"done\" />" "</scxml>"; std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); + assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } - if (1) { - // Initial with no transitions + { + // invoke with param and content, perfectly acceptable const char* xml = "<scxml>" " <state id=\"start\">" - " <initial />" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" + " <invoke type=\"scxml\">" + " <param name=\"foo\" expr=\"3\" />" + " <content>Foo!</content>" + " </invoke>" " </state>" - " <final id=\"done\" />" "</scxml>"; std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"foo\"]") != issueLocations.end()); // unreachable - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); - assert(issueLocations.size() == 2); + assert(issueLocations.size() == 0); } - if (1) { - // History transition with event + { + // invoke with namelist and content, perfectly acceptable const char* xml = "<scxml>" - " <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 id=\"start\">" + " <invoke type=\"scxml\" namelist=\"var1\">" + " <content>Foo!</content>" + " </invoke>" " </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); + assert(issueLocations.size() == 0); } - if (1) { - // History transition with condition + { + // donedata with content and param, not allowed const char* xml = "<scxml>" - " <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 id=\"start\">" + " <donedata>" + " <param name=\"foo\" expr=\"3\" />" + " <content>Foo!</content>" + " </donedata>" " </state>" - " <final id=\"done\" />" "</scxml>"; std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.find("//state[@id=\"start\"]/donedata[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } + } + return true; +} - if (1) { - // Send to unknown IO Processor +bool optimallyEnabled() { + if (1) { + // Transition can never be optimally enabled (conditionless, eventless) + + const char* xml = + "<scxml>" + " <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>" + " <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); + } + return true; +} - const char* xml = - "<scxml>" - " <state id=\"start\">" - " <onentry>" - " <send type=\"non-existant\" />" - " </onentry>" - " </state>" - "</scxml>"; +bool invalidInitial() { + if (1) { + // Initial attribute has invalid target state - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + const char* xml = + "<scxml initial=\"foo\">" + "</scxml>"; - if (1) { - // SCXML document requires unknown datamodel + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("/scxml[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } - const char* xml = - "<scxml datamodel=\"non-existant\">" - "</scxml>"; + if (1) { + // Initial attribute with target outside of children - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("/scxml[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + const char* xml = + "<scxml>" + " <state id=\"start\" initial=\"foo done\">" + " <state id=\"foo\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; - if (1) { - // Unknown executable content element + 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>" + " <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); // there are actually two issues with the transition + } + if (1) { + // Initial history transition with target outside of children + + const char* xml = + "<scxml>" + " <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>" + " <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); + } - const char* xml = - "<scxml>" - " <state id=\"start\">" - " <onentry>" - " <nonexistant />" - " </onentry>" - " </state>" - "</scxml>"; + if (1) { + // Initial transition with event + const char* xml = + "<scxml>" + " <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); + } - 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) { + // Initial transition with condition + const char* xml = + "<scxml>" + " <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 (Factory::getInstance()->hasDataModel("ecmascript")) { - // Syntax error in script + if (1) { + // Initial with multiple transitions + const char* xml = + "<scxml>" + " <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); + } - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <script>" - " $wfwegr^ " - " </script>" - "</scxml>"; + if (1) { + // Initial with no transitions + const char* xml = + "<scxml>" + " <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=\"foo\"]") != issueLocations.end()); // unreachable + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); + assert(issueLocations.size() == 2); + } + return true; +} - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("/scxml[1]/script[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } +bool invalidHistory() { + if (1) { + // History transition with event + const char* xml = + "<scxml>" + " <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 (Factory::getInstance()->hasDataModel("ecmascript")) { - // Syntax error in cond attribute + if (1) { + // History transition with condition + const char* xml = + "<scxml>" + " <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); + } + return true; +} - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <if cond=\"%2345\">" - " <elseif cond=\"%2345\" />" - " </if>" - " </onentry>" - " <transition cond=\"%2345\" />" - " </state>" - "</scxml>"; +bool unknownIOProc() { + if (1) { + // Send to unknown IO Processor + + const char* xml = + "<scxml>" + " <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); + } - 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); - } + return true; +} - if (Factory::getInstance()->hasDataModel("ecmascript")) { - // Syntax error in expr attribute +bool unknownDataModel() { + if (1) { + // SCXML document requires unknown datamodel - 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>"; + const char* xml = + "<scxml datamodel=\"non-existant\">" + "</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); - } + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("/scxml[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } - if (Factory::getInstance()->hasDataModel("ecmascript")) { - // Syntax error with foreach + return true; +} - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <foreach item=\"%2345\" index=\"%2345\" array=\"%2345\">" - " </foreach>" - " </onentry>" - " </state>" - "</scxml>"; +bool unknownExecContent() { + if (1) { + // Unknown executable content element + + const char* xml = + "<scxml>" + " <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); + } - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/foreach[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + return true; +} - if (Factory::getInstance()->hasDataModel("ecmascript")) { - // Syntax error with send +bool syntaxErrors() { + if (Factory::getInstance()->hasDataModel("ecmascript")) { + // Syntax error in script - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <send eventexpr=\"%2345\" targetexpr=\"%2345\" typeexpr=\"%2345\" idlocation=\"%2345\" delayexpr=\"%2345\" />" - " </onentry>" - " </state>" - "</scxml>"; + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <script>" + " $wfwegr^ " + " </script>" + "</scxml>"; - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("/scxml[1]/script[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } - if (Factory::getInstance()->hasDataModel("ecmascript")) { - // Syntax error with invoke + if (Factory::getInstance()->hasDataModel("ecmascript")) { + // 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); + } - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <invoke typeexpr=\"%2345\" srcexpr=\"%2345\" idlocation=\"%2345\" />" - " </state>" - "</scxml>"; + if (Factory::getInstance()->hasDataModel("ecmascript")) { + // 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); + } - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + if (Factory::getInstance()->hasDataModel("ecmascript")) { + // 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 (Factory::getInstance()->hasDataModel("ecmascript")) { - // Syntax error with cancel + if (Factory::getInstance()->hasDataModel("ecmascript")) { + // 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); + } - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <cancel sendidexpr=\"%2345\" />" - " </onentry>" - " </state>" - "</scxml>"; + if (Factory::getInstance()->hasDataModel("ecmascript")) { + // Syntax error with invoke - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/cancel[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + 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 (Factory::getInstance()->hasDataModel("ecmascript")) { + // 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 true; +} + +int main(int argc, char** argv) { + + factory = Factory::getInstance(); + return EXIT_SUCCESS; + try { + using namespace XERCESC_NS; + + int iterations = 1; + + while(iterations--) { + + endlessLoop(); + unreachableState(); + invalidParents(); + noIdAttr(); + duplicateIdAttr(); + invalidTarget(); + uselessHistory1(); + uselessHistory2(); + illegalCompletion(); + attributeConstraints(); + optimallyEnabled(); + invalidInitial(); + invalidHistory(); + unknownIOProc(); + unknownDataModel(); + unknownExecContent(); + syntaxErrors(); + + } + } catch (ErrorEvent e) { + std::cout << e; + return EXIT_FAILURE; } return EXIT_SUCCESS; |