summaryrefslogtreecommitdiffstats
path: root/test/src/test-issue-reporting.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/src/test-issue-reporting.cpp')
-rw-r--r--test/src/test-issue-reporting.cpp231
1 files changed, 218 insertions, 13 deletions
diff --git a/test/src/test-issue-reporting.cpp b/test/src/test-issue-reporting.cpp
index 98c2a21..e93ba58 100644
--- a/test/src/test-issue-reporting.cpp
+++ b/test/src/test-issue-reporting.cpp
@@ -6,7 +6,12 @@ using namespace uscxml;
std::set<std::string> issueLocationsForXML(const std::string xml) {
Interpreter interpreter = Interpreter::fromXML(xml, "");
- std::list<InterpreterIssue> issues = interpreter.validate();
+
+ // common xmlns and version requirement on scxml attribute
+ interpreter.getDocument().getDocumentElement().setAttribute("xmlns", "http://www.w3.org/2005/07/scxml");
+ interpreter.getDocument().getDocumentElement().setAttribute("version", "1.0");
+
+ std::list<InterpreterIssue> issues = interpreter.validate();
std::set<std::string> issueLocations;
@@ -61,7 +66,7 @@ int main(int argc, char** argv) {
}
if (1) {
- // Unreachable states
+ // Unreachable states 1
const char* xml =
"<scxml datamodel=\"ecmascript\">"
@@ -82,7 +87,6 @@ int main(int argc, char** argv) {
if (1) {
// Invalid parents
-
const char* xml =
"<scxml datamodel=\"ecmascript\">"
" <onentry>"
@@ -97,6 +101,7 @@ int main(int argc, char** argv) {
if (1) {
// State has no 'id' attribute
+ // *** This is not actually an error! ***
const char* xml =
"<scxml datamodel=\"ecmascript\">"
" <state>"
@@ -137,7 +142,108 @@ int main(int argc, char** argv) {
assert(issueLocations.size() == 1);
}
-
+ if (1) {
+ // Useless history 1
+
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" initial=\"bar\">"
+ " <history id=\"bar\" />"
+ " <state id=\"baz\" />"
+ " <transition event=\"e.foo\" target=\"done\" />"
+ " <transition event=\"e.bar\" target=\"baz\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ if (1) {
+ // Useless history 2
+
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" initial=\"bar\">"
+ " <history id=\"bar\">"
+ " <transition target=\"foo\" />"
+ " </history>"
+ " <transition target=\"done\" />"
+ " <state id=\"foo\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ if (1) {
+ // No legal completion
+
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" initial=\"foo bar\">"
+ " <state id=\"foo\" />"
+ " <state id=\"bar\" />"
+ " <transition target=\"foo bar\" />"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
+ assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end());
+ assert(issueLocations.size() == 2);
+ }
+
+ if (1) {
+ // attribute constraints
+
+ {
+ // initial attribute and <initial> child
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" initial=\"foo\">"
+ " <initial></initial>"
+ " <state id=\"foo\" />"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+ {
+ // initial attribute with atomic state
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" initial=\"\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+ {
+ // initial child with atomic state
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <initial />"
+ " </state>"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+
+ }
+ }
+
+
if (1) {
// Transition can never be optimally enabled (conditionless, eventless)
@@ -185,21 +291,120 @@ int main(int argc, char** argv) {
assert(issueLocations.size() == 1);
}
- if (1) {
- // Invoke with unknown type
+ if (1) {
+ // Initial attribute with target outside of children
+
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" initial=\"foo done\">"
+ " <state id=\"foo\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ if (1) {
+ // Initial transition with target outside of children
+
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <initial>"
+ " <transition target=\"foo done\" />"
+ " </initial>"
+ " <state id=\"foo\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ if (1) {
+ // Initial history transition with target outside of children
+
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\" initial=\"bar\">"
+ " <history id=\"bar\">"
+ " <transition target=\"foo done\" />"
+ " </history>"
+ " <state id=\"foo\">"
+ " <transition target=\"baz\" />"
+ " </state>"
+ " <state id=\"baz\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
+ if (1) {
+ // Initial transition with target outside of children
+
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <initial>"
+ " <transition target=\"foo done\" />"
+ " </initial>"
+ " <state id=\"foo\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
- const char* xml =
- "<scxml datamodel=\"ecmascript\">"
- " <state id=\"start\">"
- " <invoke type=\"non-existant\" />"
- " </state>"
- "</scxml>";
+ if (1) {
+ // Initial transition with event
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <initial>"
+ " <transition event=\"e.foo\" target=\"foo\" />"
+ " </initial>"
+ " <state id=\"foo\" />"
+ " <transition event=\"e.bar\" target=\"done\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
std::set<std::string> issueLocations = issueLocationsForXML(xml);
- assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end());
+ assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end());
assert(issueLocations.size() == 1);
}
+ if (1) {
+ // Initial transition with condition
+ const char* xml =
+ "<scxml datamodel=\"ecmascript\">"
+ " <state id=\"start\">"
+ " <initial>"
+ " <transition cond=\"true\" target=\"foo\" />"
+ " </initial>"
+ " <state id=\"foo\" />"
+ " <transition event=\"e.bar\" target=\"done\" />"
+ " </state>"
+ " <final id=\"done\" />"
+ "</scxml>";
+
+ std::set<std::string> issueLocations = issueLocationsForXML(xml);
+ assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end());
+ assert(issueLocations.size() == 1);
+ }
+
if (1) {
// Send to unknown IO Processor