summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorStefan Radomski <github@mintwerk.de>2017-01-27 21:54:43 (GMT)
committerStefan Radomski <github@mintwerk.de>2017-01-27 21:54:43 (GMT)
commit7f83038a1ef642b883417cc984d1f8ca9f0bc64b (patch)
treefd9236e866a06b250992e84bbf41324adf93a9fd /test
parentb450411ee8f0a57f3ec3909d65ecc289189e2b35 (diff)
downloaduscxml-7f83038a1ef642b883417cc984d1f8ca9f0bc64b.zip
uscxml-7f83038a1ef642b883417cc984d1f8ca9f0bc64b.tar.gz
uscxml-7f83038a1ef642b883417cc984d1f8ca9f0bc64b.tar.bz2
Reactivated BUILD_AS_PLUGINS
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt40
-rw-r--r--test/ctest/scripts/test_generated_c.cmake31
-rw-r--r--test/src/test-gen-c.cpp4
-rw-r--r--test/src/test-utils.cpp74
-rw-r--r--test/src/test-validating.cpp1323
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;