diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-03-28 23:28:46 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-03-28 23:28:46 (GMT) |
commit | 2317f2bf8beb03c60463a9482dbef23540f5c1e0 (patch) | |
tree | 9983553e5289cf622e782d0132bb1810276364d2 | |
parent | 7279ab2caf72b68126bf0c1d7e62c7d89024f9a0 (diff) | |
download | uscxml-2317f2bf8beb03c60463a9482dbef23540f5c1e0.zip uscxml-2317f2bf8beb03c60463a9482dbef23540f5c1e0.tar.gz uscxml-2317f2bf8beb03c60463a9482dbef23540f5c1e0.tar.bz2 |
Refactoring and W3C tests
- Moved core of interpreter to support various versions
- Added experimental setConfiguration()
- There can be more than one initial state
472 files changed, 14351 insertions, 2085 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index d861905..c15d948 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -401,6 +401,13 @@ file(GLOB_RECURSE USCXML_DEBUG source_group("Interpreter" FILES ${USCXML_DEBUG}) list (APPEND USCXML_FILES ${USCXML_DEBUG}) +file(GLOB_RECURSE USCXML_INTERPRETERS + src/uscxml/interpreter/*.cpp + src/uscxml/interpreter/*.h +) +source_group("Interpreter" FILES ${USCXML_INTERPRETERS}) +list (APPEND USCXML_FILES ${USCXML_INTERPRETERS}) + file(GLOB USCXML_CORE contrib/src/jsmn/jsmn.c src/uscxml/*.cpp diff --git a/apps/mmi-browser.cpp b/apps/mmi-browser.cpp index 5127d7b..b62aaee 100644 --- a/apps/mmi-browser.cpp +++ b/apps/mmi-browser.cpp @@ -10,11 +10,25 @@ #include "XGetopt.h" #endif -#ifdef HAS_SIGNAL_H -void handler(int s) { - printf("Caught SIGPIPE ############\n"); -} -#endif +class VerboseMonitor : public uscxml::InterpreterMonitor { + void onStableConfiguration(uscxml::Interpreter* interpreter) { + printConfig(interpreter->getConfiguration()); + } + + void beforeCompletion(uscxml::Interpreter* interpreter) { + printConfig(interpreter->getConfiguration()); + } + + void printConfig(const Arabica::XPath::NodeSet<std::string>& config) { + std::string seperator; + std::cout << "Config: {"; + for (int i = 0; i < config.size(); i++) { + std::cout << seperator << ATTR(config[i], "id"); + seperator = ", "; + } + std::cout << "}" << std::endl; + } +}; void printUsageAndExit() { printf("mmi-browser version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n"); @@ -25,8 +39,9 @@ void printUsageAndExit() { #endif printf(" URL\n"); printf("\n"); - // printf("Options\n"); - // printf("\t-l loglevel : loglevel to use\n"); + printf("Options\n"); + printf("\t-v : be verbose\n"); + printf("\n"); exit(1); } @@ -34,35 +49,20 @@ int main(int argc, char** argv) { using namespace uscxml; #ifdef HAS_SIGNAL_H - // disable SIGPIPE -// struct sigaction act; -// act.sa_handler=SIG_IGN; -// sigemptyset(&act.sa_mask); -// act.sa_flags=0; -// sigaction(SIGPIPE, &act, NULL); - - // signal(SIGPIPE, handler); - signal(SIGPIPE, SIG_IGN); - - // struct sigaction act; - // int r; - // memset(&act, 0, sizeof(act)); - // act.sa_handler = SIG_IGN; - // act.sa_flags = SA_RESTART; - // r = sigaction(SIGPIPE, &act, NULL); - #endif if (argc < 2) { printUsageAndExit(); } + bool verbose = false; + #ifndef _WIN32 opterr = 0; #endif int option; - while ((option = getopt(argc, argv, "l:p:")) != -1) { + while ((option = getopt(argc, argv, "vl:p:")) != -1) { switch(option) { case 'l': google::InitGoogleLogging(optarg); @@ -70,6 +70,9 @@ int main(int argc, char** argv) { case 'p': uscxml::Factory::pluginPath = optarg; break; + case 'v': + verbose = true; + break; case '?': break; default: @@ -87,9 +90,14 @@ int main(int argc, char** argv) { interpreter->setCmdLineOptions(argc, argv); // interpreter->setCapabilities(Interpreter::CAN_NOTHING); // interpreter->setCapabilities(Interpreter::CAN_BASIC_HTTP | Interpreter::CAN_GENERIC_HTTP); + + if (verbose) { + VerboseMonitor* vm = new VerboseMonitor(); + interpreter->addMonitor(vm); + } + interpreter->start(); while(interpreter->runOnMainThread(25)); - // interpreter->interpret(); delete interpreter; } diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 8e9165e..e59ef5f 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -19,6 +19,8 @@ #include <assert.h> #include <algorithm> +#include "uscxml/interpreter/InterpreterDraft6.h" + #define VERBOSE 0 namespace uscxml { @@ -31,7 +33,7 @@ const std::string Interpreter::getUUID() { return boost::lexical_cast<std::string>(uuidGen()); } -Interpreter::Interpreter() : Arabica::SAX2DOM::Parser<std::string>() { +Interpreter::Interpreter() { _lastRunOnMainThread = 0; _nsURL = "*"; _thread = NULL; @@ -51,11 +53,9 @@ Interpreter::Interpreter() : Arabica::SAX2DOM::Parser<std::string>() { Interpreter* Interpreter::fromDOM(const Arabica::DOM::Node<std::string>& node) { Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); - Interpreter* interpreter = new Interpreter(); + Interpreter* interpreter = new InterpreterDraft6(); interpreter->_document = domFactory.createDocument("http://www.w3.org/2005/07/scxml", "scxml", 0); interpreter->_document.appendChild(node); - interpreter->init(); - return interpreter; } @@ -80,7 +80,6 @@ Interpreter* Interpreter::fromURI(const std::string& uri) { Interpreter* interpreter = NULL; - // this is required for windows filenames and does not harm on unices if (boost::iequals(absUrl.scheme(), "file")) { Arabica::SAX::InputSource<std::string> inputSource; inputSource.setSystemId(absUrl.path()); @@ -107,6 +106,59 @@ Interpreter* Interpreter::fromURI(const std::string& uri) { return interpreter; } +Interpreter* Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& source) { + Interpreter* interpreter = new InterpreterDraft6(); + + SCXMLParser* parser = new SCXMLParser(interpreter); + if(!parser->parse(source) || !parser->getDocument().hasChildNodes()) { + if(parser->_errorHandler.errorsReported()) { + LOG(ERROR) << "could not parse input:"; + LOG(ERROR) << parser->_errorHandler.errors() << std::endl; + } else { + Arabica::SAX::InputSourceResolver resolver(source, Arabica::default_string_adaptor<std::string>()); + if (!resolver.resolve()) { + LOG(ERROR) << source.getSystemId() << ": no such file"; + } + } + delete parser; + delete interpreter; + return NULL; + } else { + interpreter->_document = parser->getDocument(); + } + // interpreter->init(); + delete parser; + return interpreter; +} + +SCXMLParser::SCXMLParser(Interpreter* interpreter) : _interpreter(interpreter) { + Arabica::SAX::CatchErrorHandler<std::string> errorHandler; + setErrorHandler(errorHandler); +} + +void SCXMLParser::startPrefixMapping(const std::string& prefix, const std::string& uri) { +#if 0 + std::cout << "starting prefix mapping " << prefix << ": " << uri << std::endl; +#endif + if (boost::iequals(uri, "http://www.w3.org/2005/07/scxml")) { + _interpreter->_nsURL = uri; + if (prefix.size() == 0) { + LOG(INFO) << "Mapped default namespace to 'scxml:'"; + _interpreter->_xpathPrefix = "scxml:"; + _interpreter->_nsContext.addNamespaceDeclaration(uri, "scxml"); + _interpreter->_nsToPrefix[uri] = "scxml"; + } else { + _interpreter->_xpathPrefix = prefix + ":"; + _interpreter->_xmlNSPrefix = _interpreter->_xpathPrefix; + _interpreter->_nsContext.addNamespaceDeclaration(uri, prefix); + _interpreter->_nsToPrefix[uri] = prefix; + } + } else { + _interpreter->_nsContext.addNamespaceDeclaration(uri, prefix); + _interpreter->_nsToPrefix[uri] = prefix; + } +} + void Interpreter::setName(const std::string& name) { if (!_running) { _name = name; @@ -147,83 +199,6 @@ bool Interpreter::toAbsoluteURI(URL& uri) { return false; } -void Interpreter::startPrefixMapping(const std::string& prefix, const std::string& uri) { -#if 0 - std::cout << "starting prefix mapping " << prefix << ": " << uri << std::endl; -#endif - if (boost::iequals(uri, "http://www.w3.org/2005/07/scxml")) { - _nsURL = uri; - if (prefix.size() == 0) { - LOG(INFO) << "Mapped default namespace to 'scxml:'"; - _xpathPrefix = "scxml:"; - _nsContext.addNamespaceDeclaration(uri, "scxml"); - _nsToPrefix[uri] = "scxml"; - } else { - _xpathPrefix = prefix + ":"; - _xmlNSPrefix = _xpathPrefix; - _nsContext.addNamespaceDeclaration(uri, prefix); - _nsToPrefix[uri] = prefix; - } - } else { - _nsContext.addNamespaceDeclaration(uri, prefix); - _nsToPrefix[uri] = prefix; - } -} - -Interpreter* Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& source) { - Interpreter* interpreter = new Interpreter(); - - Arabica::SAX::CatchErrorHandler<std::string> errorHandler; - interpreter->setErrorHandler(errorHandler); - if(!interpreter->parse(source) || !interpreter->Arabica::SAX2DOM::Parser<std::string>::getDocument().hasChildNodes()) { - if(errorHandler.errorsReported()) { - LOG(ERROR) << "could not parse input:"; - LOG(ERROR) << errorHandler.errors() << std::endl; - } else { - Arabica::SAX::InputSourceResolver resolver(source, Arabica::default_string_adaptor<std::string>()); - if (!resolver.resolve()) { - LOG(ERROR) << source.getSystemId() << ": no such file"; - } - } - delete interpreter; - return NULL; - } else { - interpreter->_document = interpreter->Arabica::SAX2DOM::Parser<std::string>::getDocument(); - } -// interpreter->init(); - return interpreter; -} - -void Interpreter::init() { - if (_document) { - NodeList<std::string> scxmls = _document.getElementsByTagNameNS(_nsURL, "scxml"); - if (scxmls.getLength() > 0) { - _scxml = (Arabica::DOM::Element<std::string>)scxmls.item(0); - - // setup xpath and check that it works - _xpath.setNamespaceContext(_nsContext); - Arabica::XPath::NodeSet<std::string> scxmls = _xpath.evaluate("/" + _xpathPrefix + "scxml", _document).asNodeSet(); - assert(scxmls.size() > 0); - assert(scxmls[0] == _scxml); - - if (_name.length() == 0) - _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : getUUID()); - - normalize(_document); - - if (_capabilities & CAN_GENERIC_HTTP) - _httpServlet = new InterpreterServlet(this); - - _sendQueue = new DelayedEventQueue(); - _sendQueue->start(); - - } else { - LOG(ERROR) << "Cannot find SCXML element" << std::endl; - } - } - _isInitialized = true; -} - Interpreter::~Interpreter() { if (_thread) { _running = false; @@ -280,140 +255,34 @@ bool Interpreter::runOnMainThread(int fps, bool blocking) { return (_thread != NULL); } -// see: http://www.w3.org/TR/scxml/#AlgorithmforSCXMLInterpretation -void Interpreter::interpret() { - if (!_isInitialized) - init(); - - if (!_scxml) - return; -// dump(); - - _sessionId = getUUID(); - - std::string datamodelName; - if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "datamodel")) - datamodelName = ATTR(_scxml, "datamodel"); - if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "profile")) // SCION SCXML uses profile to specify datamodel - datamodelName = ATTR(_scxml, "profile"); - _dataModel = Factory::createDataModel(datamodelName, this); - if(datamodelName.length() > 0 && !_dataModel) { - LOG(ERROR) << "No datamodel for " << datamodelName << " registered"; - } - - if (_dataModel) { - _dataModel.assign("_x.args", _cmdLineOptions); - if (_httpServlet) { - Data data; - data.compound["location"] = Data(_httpServlet->getURL(), Data::VERBATIM); - _dataModel.assign("_ioprocessors['http']", data); - } - } - - setupIOProcessors(); - - _running = true; - _binding = (HAS_ATTR(_scxml, "binding") && boost::iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); - - // @TODO: Reread http://www.w3.org/TR/scxml/#DataBinding - - if (_dataModel && _binding == EARLY) { - // initialize all data elements - NodeSet<std::string> dataElems = _xpath.evaluate("//" + _xpathPrefix + "data", _document).asNodeSet(); - for (unsigned int i = 0; i < dataElems.size(); i++) { - initializeData(dataElems[i]); - } - } else if(_dataModel) { - // initialize current data elements - NodeSet<std::string> topDataElems = filterChildElements(_xmlNSPrefix + "data", filterChildElements(_xmlNSPrefix + "datamodel", _scxml)); - for (unsigned int i = 0; i < topDataElems.size(); i++) { - initializeData(topDataElems[i]); - } - } - - // executeGlobalScriptElements - NodeSet<std::string> globalScriptElems = _xpath.evaluate("/" + _xpathPrefix + "scxml/" + _xpathPrefix + "script", _document).asNodeSet(); - for (unsigned int i = 0; i < globalScriptElems.size(); i++) { - if (_dataModel) - executeContent(globalScriptElems[i]); - } - - // initial transition might be implict - NodeSet<std::string> initialTransitions = _xpath.evaluate("/" + _xpathPrefix + "scxml/" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", _document).asNodeSet(); - if (initialTransitions.size() == 0) { - Arabica::DOM::Element<std::string> initialState = (Arabica::DOM::Element<std::string>)getInitialState(); - Arabica::DOM::Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial"); - initialElem.setAttribute("generated", "true"); - Arabica::DOM::Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition"); - transitionElem.setAttribute("target", initialState.getAttribute("id")); - initialElem.appendChild(transitionElem); - _scxml.appendChild(initialElem); - initialTransitions.push_back(transitionElem); - } - enterStates(initialTransitions); - -// assert(hasLegalConfiguration()); - mainEventLoop(); - - if (_parentQueue) { - // send one final event to unblock eventual listeners - Event quit; - quit.name = "done.state.scxml"; - _parentQueue->push(quit); - } - - // set datamodel to null from this thread - if(_dataModel) - _dataModel = DataModel(); - -} - -/** - * Called with a single data element from the topmost datamodel element. - */ -void Interpreter::initializeData(const Arabica::DOM::Node<std::string>& data) { - if (!_dataModel) { - LOG(ERROR) << "Cannot initialize data when no datamodel is given!"; - return; - } - try { - if (!HAS_ATTR(data, "id")) { - LOG(ERROR) << "Data element has no id!"; - return; - } - - if (HAS_ATTR(data, "expr")) { - std::string value = ATTR(data, "expr"); - _dataModel.assign(ATTR(data, "id"), value); - } else if (HAS_ATTR(data, "src")) { - URL srcURL(ATTR(data, "src")); - if (!srcURL.isAbsolute()) - toAbsoluteURI(srcURL); - - std::stringstream ss; - if (_cachedURLs.find(srcURL.asString()) != _cachedURLs.end()) { - ss << _cachedURLs[srcURL.asString()]; - } else { - ss << srcURL; - _cachedURLs[srcURL.asString()] = srcURL; - } - _dataModel.assign(ATTR(data, "id"), ss.str()); - - } else if (data.hasChildNodes()) { - // search for the text node with the actual script - NodeList<std::string> dataChilds = data.getChildNodes(); - for (int i = 0; i < dataChilds.getLength(); i++) { - if (dataChilds.item(i).getNodeType() == Node_base::TEXT_NODE) { - Data value = Data(dataChilds.item(i).getNodeValue()); - _dataModel.assign(ATTR(data, "id"), value); - break; - } - } +void Interpreter::init() { + if (_document) { + NodeList<std::string> scxmls = _document.getElementsByTagNameNS(_nsURL, "scxml"); + if (scxmls.getLength() > 0) { + _scxml = (Arabica::DOM::Element<std::string>)scxmls.item(0); + + // setup xpath and check that it works + _xpath.setNamespaceContext(_nsContext); + Arabica::XPath::NodeSet<std::string> scxmls = _xpath.evaluate("/" + _xpathPrefix + "scxml", _document).asNodeSet(); + assert(scxmls.size() > 0); + assert(scxmls[0] == _scxml); + + if (_name.length() == 0) + _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : getUUID()); + + normalize(_document); + + if (_capabilities & CAN_GENERIC_HTTP) + _httpServlet = new InterpreterServlet(this); + + _sendQueue = new DelayedEventQueue(); + _sendQueue->start(); + + } else { + LOG(ERROR) << "Cannot find SCXML element" << std::endl; } - - } catch (Event e) { - LOG(ERROR) << "Syntax error in data element:" << std::endl << e << std::endl; } + _isInitialized = true; } void Interpreter::normalize(const Arabica::DOM::Document<std::string>& node) { @@ -476,176 +345,6 @@ void Interpreter::normalize(const Arabica::DOM::Document<std::string>& node) { #endif } -void Interpreter::mainEventLoop() { - std::set<InterpreterMonitor*>::iterator monIter; - - while(_running) { - NodeSet<std::string> enabledTransitions; - _stable = false; - - // Here we handle eventless transitions and transitions - // triggered by internal events until machine is stable - while(_running && !_stable) { -#if 0 - std::cout << "Configuration: "; - for (int i = 0; i < _configuration.size(); i++) { - std::cout << ATTR(_configuration[i], "id") << ", "; - } - std::cout << std::endl; -#endif - monIter = _monitors.begin(); - while(monIter != _monitors.end()) { - try { - (*monIter)->beforeMicroStep(this); - } catch (Event e) { - LOG(ERROR) << "Syntax error when calling beforeMicroStep on monitors: " << std::endl << e << std::endl; - } catch (...) { - LOG(ERROR) << "An exception occured when calling beforeMicroStep on monitors"; - } - monIter++; - } - - enabledTransitions = selectEventlessTransitions(); - if (enabledTransitions.size() == 0) { - if (_internalQueue.size() == 0) { - _stable = true; - } else { - _currEvent = _internalQueue.front(); - _internalQueue.pop_front(); -#if VERBOSE - std::cout << "Received internal event " << _currEvent.name << std::endl; -#endif - if (_dataModel) - _dataModel.setEvent(_currEvent); - enabledTransitions = selectTransitions(_currEvent.name); - } - } - if (!enabledTransitions.empty()) { - monIter = _monitors.begin(); - while(monIter != _monitors.end()) { - try { - (*monIter)->beforeTakingTransitions(this, enabledTransitions); - } catch (Event e) { - LOG(ERROR) << "Syntax error when calling beforeTakingTransitions on monitors: " << std::endl << e << std::endl; - } catch (...) { - LOG(ERROR) << "An exception occured when calling beforeTakingTransitions on monitors"; - } - monIter++; - } - microstep(enabledTransitions); - } - } - - for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _statesToInvoke[i]); - for (unsigned int j = 0; j < invokes.size(); j++) { - invoke(invokes[j]); - } - } - - _statesToInvoke = NodeSet<std::string>(); - if (!_internalQueue.empty()) - continue; - - // assume that we have a legal configuration as soon as the internal queue is empty -// assert(hasLegalConfiguration()); - - monIter = _monitors.begin(); -// if (!_sendQueue || _sendQueue->isEmpty()) { - while(monIter != _monitors.end()) { - try { - (*monIter)->onStableConfiguration(this); - } catch (Event e) { - LOG(ERROR) << "Syntax error when calling onStableConfiguration on monitors: " << std::endl << e << std::endl; - } catch (...) { - LOG(ERROR) << "An exception occured when calling onStableConfiguration on monitors"; - } - monIter++; - } -// } - - // whenever we have a stable configuration, run the mainThread hooks with 200fps - while(_externalQueue.isEmpty() && _thread == NULL) { - runOnMainThread(200); - } - - _currEvent = _externalQueue.pop(); -#if VERBOSE - std::cout << "Received externalEvent event " << _currEvent.name << std::endl; -#endif - _currEvent.type = Event::EXTERNAL; // make sure it is set to external - if (!_running) - exitInterpreter(); - - if (_dataModel && boost::iequals(_currEvent.name, "cancel.invoke." + _sessionId)) - break; - - if (_dataModel) - try { - _dataModel.setEvent(_currEvent); - } catch (Event e) { - LOG(ERROR) << "Syntax error while setting external event:" << std::endl << e << std::endl; - } - for (unsigned int i = 0; i < _configuration.size(); i++) { - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _configuration[i]); - for (unsigned int j = 0; j < invokes.size(); j++) { - Arabica::DOM::Element<std::string> invokeElem = (Arabica::DOM::Element<std::string>)invokes[j]; - std::string invokeId; - if (HAS_ATTR(invokeElem, "id")) - invokeId = ATTR(invokeElem, "id"); - if (HAS_ATTR(invokeElem, "idlocation") && _dataModel) - invokeId = _dataModel.evalAsString(ATTR(invokeElem, "idlocation")); - - std::string autoForward = invokeElem.getAttribute("autoforward"); - if (boost::iequals(invokeId, _currEvent.invokeid)) { - - Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_xmlNSPrefix + "finalize", invokeElem); - for (int k = 0; k < finalizes.size(); k++) { - Arabica::DOM::Element<std::string> finalizeElem = Arabica::DOM::Element<std::string>(finalizes[k]); - executeContent(finalizeElem); - } - - } - if (boost::iequals(autoForward, "true")) { - try { - _invokers[invokeId].send(_currEvent); - } catch(...) { - LOG(ERROR) << "Exception caught while sending event to invoker " << invokeId; - } - } - } - } - enabledTransitions = selectTransitions(_currEvent.name); - if (!enabledTransitions.empty()) - microstep(enabledTransitions); - } - monIter = _monitors.begin(); - while(monIter != _monitors.end()) { - try { - (*monIter)->beforeCompletion(this); - } catch (Event e) { - LOG(ERROR) << "Syntax error when calling beforeCompletion on monitors: " << std::endl << e << std::endl; - } catch (...) { - LOG(ERROR) << "An exception occured when calling beforeCompletion on monitors"; - } - monIter++; - } - - exitInterpreter(); - - monIter = _monitors.begin(); - while(monIter != _monitors.end()) { - try { - (*monIter)->afterCompletion(this); - } catch (Event e) { - LOG(ERROR) << "Syntax error when calling afterCompletion on monitors: " << std::endl << e << std::endl; - } catch (...) { - LOG(ERROR) << "An exception occured when calling afterCompletion on monitors"; - } - monIter++; - } - -} void Interpreter::internalDoneSend(const Arabica::DOM::Node<std::string>& state) { if (!isState(state)) @@ -1075,55 +774,6 @@ void Interpreter::cancelInvoke(const Arabica::DOM::Node<std::string>& element) { } } -Arabica::XPath::NodeSet<std::string> Interpreter::selectTransitions(const std::string& event) { - Arabica::XPath::NodeSet<std::string> enabledTransitions; - - NodeSet<std::string> atomicStates; - for (unsigned int i = 0; i < _configuration.size(); i++) { - if (isAtomic(_configuration[i])) - atomicStates.push_back(_configuration[i]); - } - atomicStates.to_document_order(); - - for (unsigned int i = 0; i < atomicStates.size(); i++) { - NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>()); - - NodeSet<std::string> sortedAncestors; - sortedAncestors.push_back(atomicStates[i]); - sortedAncestors.insert(sortedAncestors.end(), ancestors.begin(), ancestors.end()); - - for (unsigned int j = 0; j < sortedAncestors.size(); j++) { - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", sortedAncestors[j]); - for (unsigned int k = 0; k < transitions.size(); k++) { - std::string eventName; - if (HAS_ATTR(transitions[k], "event")) { - eventName = ATTR(transitions[k], "event"); - } else if(HAS_ATTR(transitions[k], "eventexpr")) { - if (_dataModel) { - eventName = _dataModel.evalAsString(ATTR(transitions[k], "eventexpr")); - } else { - LOG(ERROR) << "Transition has eventexpr attribute with no datamodel defined"; - goto LOOP; - } - } else { - goto LOOP; - } - - if (eventName.length() > 0 && - nameMatch(eventName, event) && - hasConditionMatch(transitions[k])) { - enabledTransitions.push_back(transitions[k]); - goto LOOP; - } - } - } -LOOP: - ; - } - - enabledTransitions = filterPreempted(enabledTransitions); - return enabledTransitions; -} // see: http://www.w3.org/TR/scxml/#EventDescriptors bool Interpreter::nameMatch(const std::string& transitionEvent, const std::string& event) { @@ -1167,49 +817,10 @@ bool Interpreter::nameMatch(const std::string& transitionEvent, const std::strin return false; } -Arabica::XPath::NodeSet<std::string> Interpreter::selectEventlessTransitions() { - Arabica::XPath::NodeSet<std::string> enabledTransitions; - - NodeSet<std::string> atomicStates; - for (unsigned int i = 0; i < _configuration.size(); i++) { - if (isAtomic(_configuration[i])) - atomicStates.push_back(_configuration[i]); - } - atomicStates.to_document_order(); - - for (unsigned int i = 0; i < atomicStates.size(); i++) { - NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>()); - ancestors.push_back(atomicStates[i]); - for (unsigned int j = 0; j < ancestors.size(); j++) { - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestors[j]); - for (unsigned int k = 0; k < transitions.size(); k++) { - if (!HAS_ATTR(transitions[k], "event") && hasConditionMatch(transitions[k])) { - enabledTransitions.push_back(transitions[k]); - goto LOOP; - } - } - -#if 0 - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestors[j]); - for (unsigned int k = 0; k < transitions.size(); k++) { - if (!((Arabica::DOM::Element<std::string>)transitions[k]).hasAttribute("event") && hasConditionMatch(transitions[k])) { - enabledTransitions.push_back(transitions[k]); - goto LOOP; - } - } -#endif - } -LOOP: - ; - } - - enabledTransitions = filterPreempted(enabledTransitions); - return enabledTransitions; -} bool Interpreter::hasConditionMatch(const Arabica::DOM::Node<std::string>& conditional) { - if (HAS_ATTR(conditional, "cond")) { + if (HAS_ATTR(conditional, "cond") && ATTR(conditional, "cond").length() > 0) { if (!_dataModel) { LOG(ERROR) << "Cannot check a condition without a datamodel"; return false; @@ -1224,129 +835,6 @@ bool Interpreter::hasConditionMatch(const Arabica::DOM::Node<std::string>& condi return true; // no condition is always true } -Arabica::XPath::NodeSet<std::string> Interpreter::filterPreempted(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { - Arabica::XPath::NodeSet<std::string> filteredTransitions; - for (unsigned int i = 0; i < enabledTransitions.size(); i++) { - Arabica::DOM::Node<std::string> t = enabledTransitions[i]; - for (unsigned int j = i+1; j < enabledTransitions.size(); j++) { - Arabica::DOM::Node<std::string> t2 = enabledTransitions[j]; - if (isPreemptingTransition(t2, t)) { -#if VERBOSE - std::cout << "Transition preempted!: " << std::endl << t2 << std::endl << t << std::endl; -#endif - goto LOOP; - } - } - filteredTransitions.push_back(t); -LOOP: - ; - } - return filteredTransitions; -} - -bool Interpreter::isPreemptingTransition(const Arabica::DOM::Node<std::string>& t1, const Arabica::DOM::Node<std::string>& t2) { - assert(t1); - assert(t2); - -#if VERBOSE - std::cout << "Checking preemption: " << std::endl << t1 << std::endl << t2 << std::endl; -#endif - -#if 1 - if (t1 == t2) - return false; - if (isWithinSameChild(t1) && (!isTargetless(t2) && !isWithinSameChild(t2))) - return true; - if (!isTargetless(t1) && !isWithinSameChild(t1)) - return true; - return false; -#endif - -#if 0 - // isPreempted from chris nuernberger - if (isTargetless(t1)) - return false; - - Arabica::DOM::Node<std::string> existingRoot = getTransitionSubgraph(t1); - Arabica::DOM::Node<std::string> nextRoot = getTransitionSubgraph(t2); - - if (existingRoot == nextRoot || isDescendant(existingRoot, nextRoot) || isDescendant(nextRoot, existingRoot)) - return true; - - return false; -#endif -} - -/** - * filterPreempted approach from chris nuernberger - */ -#if 0 -Arabica::DOM::Node<std::string> Interpreter::getTransitionSubgraph(const Arabica::DOM::Node<std::string>& transition) { - Arabica::XPath::NodeSet<std::string> targets = getTargetStates(transition); - Arabica::DOM::Node<std::string> source = getSourceState(transition); - - if (!targets.size() == 0) - return source; - - if (boost::iequals(ATTR(transition, "type"), "internal") && isCompound(source)) { - bool allDescendants = true; - for (int i = 0; i < targets.size(); i++) { - if (!isDescendant(targets[i], source)) { - allDescendants = false; - break; - } - } - if (allDescendants) - return source; - } - - targets.push_back(source); - return findLCCA(targets); -} -#endif - -void Interpreter::microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { -#if 0 - std::cout << "Transitions: "; - for (int i = 0; i < enabledTransitions.size(); i++) { - std::cout << ((Arabica::DOM::Element<std::string>)getSourceState(enabledTransitions[i])).getAttribute("id") << " -> " << std::endl; - NodeSet<std::string> targetSet = getTargetStates(enabledTransitions[i]); - for (int j = 0; j < targetSet.size(); j++) { - std::cout << " " << ((Arabica::DOM::Element<std::string>)targetSet[j]).getAttribute("id") << std::endl; - } - } - std::cout << std::endl; -#endif - - exitStates(enabledTransitions); - executeTransitionContent(enabledTransitions); - enterStates(enabledTransitions); -} - -void Interpreter::exitInterpreter() { - NodeSet<std::string> statesToExit = _configuration; - statesToExit.to_document_order(); - statesToExit.reverse(); - - for (int i = 0; i < statesToExit.size(); i++) { - Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_xmlNSPrefix + "onexit", statesToExit[i]); - for (int j = 0; j < onExitElems.size(); j++) { - executeContent(onExitElems[j]); - } - Arabica::XPath::NodeSet<std::string> invokeElems = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]); - for (int j = 0; j < invokeElems.size(); j++) { - cancelInvoke(invokeElems[j]); - } - if (isFinal(statesToExit[i]) && parentIsScxmlState(statesToExit[i])) { - returnDoneEvent(statesToExit[i]); - } - } - _configuration = NodeSet<std::string>(); -} - -void Interpreter::executeTransitionContent(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { - executeContent(enabledTransitions); -} void Interpreter::executeContent(const NodeList<std::string>& content) { for (unsigned int i = 0; i < content.getLength(); i++) { @@ -1392,40 +880,32 @@ void Interpreter::executeContent(const Arabica::DOM::Node<std::string>& content) if (HAS_ATTR(ifElem, "cond")) std::cout << ATTR(ifElem, "cond") << std::endl; #endif - if(hasConditionMatch(ifElem)) { - // condition is true, execute all content up to an elseif, else or end - if (ifElem.hasChildNodes()) { - NodeList<std::string> childs = ifElem.getChildNodes(); - for (unsigned int i = 0; i < childs.getLength(); i++) { - if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) - continue; - if (boost::iequals(TAGNAME(childs.item(i)), _xmlNSPrefix + "elseif") || - boost::iequals(TAGNAME(childs.item(i)), _xmlNSPrefix + "else")) + /** + * A block is everything up to or between elseifs and else. Those element + * determine whether the block is true and its executable content executed. + */ + if (ifElem.hasChildNodes()) { + bool blockIsTrue = hasConditionMatch(ifElem); + NodeList<std::string> childs = ifElem.getChildNodes(); + for (unsigned int i = 0; i < childs.getLength(); i++) { + if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + if (boost::iequals(TAGNAME(childs.item(i)), _xmlNSPrefix + "elseif") || + boost::iequals(TAGNAME(childs.item(i)), _xmlNSPrefix + "else")) { + if (blockIsTrue) { + // last block was true, break here break; - executeContent(childs.item(i)); - } - } - } else { - // condition does not match - do we have an elsif? - if (ifElem.hasChildNodes()) { - NodeSet<std::string> elseifElem = filterChildElements(_xmlNSPrefix + "elseif", ifElem); - for (unsigned int i = 0; i < elseifElem.size(); i++) { -#if 0 - if (HAS_ATTR(elseifElem[i], "cond")) - std::cout << ATTR(elseifElem[i], "cond") << std::endl; -#endif - if (hasConditionMatch(elseifElem[i])) { - executeContent(elseifElem[i].getChildNodes()); - goto ELSIF_ELEM_MATCH; + } else { + // is this block the one to execute? + blockIsTrue = hasConditionMatch(childs.item(i)); + } + } else { + if (blockIsTrue) { + executeContent(childs.item(i)); } } - NodeSet<std::string> elseElem = filterChildElements(_xmlNSPrefix + "else", ifElem); - if (elseElem.size() > 0) - executeContent(elseElem[0].getChildNodes()); } } -ELSIF_ELEM_MATCH: - ; } else if (boost::iequals(TAGNAME(content), _xmlNSPrefix + "elseif")) { std::cerr << "Found single elsif to evaluate!" << std::endl; } else if (boost::iequals(TAGNAME(content), _xmlNSPrefix + "else")) { @@ -1578,589 +1058,6 @@ ELSIF_ELEM_MATCH: void Interpreter::returnDoneEvent(const Arabica::DOM::Node<std::string>& state) { } -void Interpreter::exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { - NodeSet<std::string> statesToExit; - std::set<InterpreterMonitor*>::iterator monIter; - -#if VERBOSE - std::cout << "Enabled exit transitions: " << std::endl; - for (int i = 0; i < enabledTransitions.size(); i++) { - std::cout << enabledTransitions[i] << std::endl; - } - std::cout << std::endl; -#endif - - for (int i = 0; i < enabledTransitions.size(); i++) { - Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]); - if (!isTargetless(transition)) { - std::string transitionType = (boost::iequals(transition.getAttribute("type"), "internal") ? "internal" : "external"); - NodeSet<std::string> tStates = getTargetStates(transition); - Arabica::DOM::Node<std::string> ancestor; - Arabica::DOM::Node<std::string> source = getSourceState(transition); - - bool allDescendants = true; - for (int j = 0; j < tStates.size(); j++) { - if (!isDescendant(tStates[j], source)) { - allDescendants = false; - break; - } - } - if (boost::iequals(transitionType, "internal") && - isCompound(source) && - allDescendants) { - ancestor = source; - } else { - NodeSet<std::string> tmpStates; - tmpStates.push_back(source); - tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end()); - -#if VERBOSE - std::cout << "tmpStates: "; - for (int i = 0; i < tmpStates.size(); i++) { - std::cout << ATTR(tmpStates[i], "id") << ", "; - } - std::cout << std::endl; -#endif - ancestor = findLCCA(tmpStates); - } - -#if VERBOSE - std::cout << "Ancestor: " << ATTR(ancestor, "id") << std::endl;; -#endif - - for (int j = 0; j < _configuration.size(); j++) { - if (isDescendant(_configuration[j], ancestor)) - statesToExit.push_back(_configuration[j]); - } - } - } - -#if VERBOSE - std::cout << "States to exit: "; - for (int i = 0; i < statesToExit.size(); i++) { - std::cout << LOCALNAME(statesToExit[i]) << ":" << ATTR(statesToExit[i], "id") << ", "; - } - std::cout << std::endl; - -#endif - - // remove statesToExit from _statesToInvoke - std::list<Arabica::DOM::Node<std::string> > tmp; - for (int i = 0; i < _statesToInvoke.size(); i++) { - if (!isMember(_statesToInvoke[i], statesToExit)) { - tmp.push_back(_statesToInvoke[i]); - } - } - _statesToInvoke = NodeSet<std::string>(); - _statesToInvoke.insert(_statesToInvoke.end(), tmp.begin(), tmp.end()); - - statesToExit.to_document_order(); - statesToExit.reverse(); - - monIter = _monitors.begin(); - while(monIter != _monitors.end()) { - try { - (*monIter)->beforeExitingStates(this, statesToExit); - } catch (Event e) { - LOG(ERROR) << "Syntax error when calling beforeExitingStates on monitors: " << std::endl << e << std::endl; - } catch (...) { - LOG(ERROR) << "An exception occured when calling beforeExitingStates on monitors"; - } - monIter++; - } - - for (int i = 0; i < statesToExit.size(); i++) { - NodeSet<std::string> histories = filterChildElements(_xmlNSPrefix + "history", statesToExit[i]); - for (int j = 0; j < histories.size(); j++) { - Arabica::DOM::Element<std::string> historyElem = (Arabica::DOM::Element<std::string>)histories[j]; - std::string historyType = (historyElem.hasAttribute("type") ? historyElem.getAttribute("type") : "shallow"); - NodeSet<std::string> historyNodes; - for (int k = 0; k < _configuration.size(); k++) { - if (boost::iequals(historyType, "deep")) { - if (isAtomic(_configuration[k]) && isDescendant(_configuration[k], statesToExit[i])) - historyNodes.push_back(_configuration[k]); - } else { - if (_configuration[k].getParentNode() == statesToExit[i]) - historyNodes.push_back(_configuration[k]); - } - } - _historyValue[historyElem.getAttribute("id")] = historyNodes; -#if 0 - std::cout << "History node " << ATTR(historyElem, "id") << " contains: "; - for (int i = 0; i < historyNodes.size(); i++) { - std::cout << ATTR(historyNodes[i], "id") << ", "; - } - std::cout << std::endl; - -#endif - - } - } - - for (int i = 0; i < statesToExit.size(); i++) { - NodeSet<std::string> onExits = filterChildElements(_xmlNSPrefix + "onExit", statesToExit[i]); - for (int j = 0; j < onExits.size(); j++) { - Arabica::DOM::Element<std::string> onExitElem = (Arabica::DOM::Element<std::string>)onExits[j]; - executeContent(onExitElem); - } - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]); - for (int j = 0; j < invokes.size(); j++) { - Arabica::DOM::Element<std::string> invokeElem = (Arabica::DOM::Element<std::string>)invokes[j]; - cancelInvoke(invokeElem); - } - } - - // remove statesToExit from _configuration - tmp.clear(); - for (int i = 0; i < _configuration.size(); i++) { - if (!isMember(_configuration[i], statesToExit)) { - tmp.push_back(_configuration[i]); - } - } - _configuration = NodeSet<std::string>(); - _configuration.insert(_configuration.end(), tmp.begin(), tmp.end()); - - monIter = _monitors.begin(); - while(monIter != _monitors.end()) { - try { - (*monIter)->afterExitingStates(this); - } catch (Event e) { - LOG(ERROR) << "Syntax error when calling afterExitingStates on monitors: " << std::endl << e << std::endl; - } catch (...) { - LOG(ERROR) << "An exception occured when calling afterExitingStates on monitors"; - } - monIter++; - } - -} - -#ifdef ORIG_ENTERSTATES -void Interpreter::enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { - NodeSet<std::string> statesToEnter; - NodeSet<std::string> statesForDefaultEntry; - std::set<InterpreterMonitor*>::iterator monIter; - -#if VERBOSE - std::cout << "Enabled enter transitions: " << std::endl; - for (int i = 0; i < enabledTransitions.size(); i++) { - std::cout << enabledTransitions[i] << std::endl; - } - std::cout << std::endl; -#endif - - for (int i = 0; i < enabledTransitions.size(); i++) { - Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]); - if (!isTargetless(transition)) { - std::string transitionType = (boost::iequals(transition.getAttribute("type"), "internal") ? "internal" : "external"); - NodeSet<std::string> tStates = getTargetStates(transition); - -#if VERBOSE - std::cout << "Target States: "; - for (int i = 0; i < tStates.size(); i++) { - std::cout << ATTR(tStates[i], "id") << ", "; - } - std::cout << std::endl; -#endif - - Arabica::DOM::Node<std::string> ancestor; - Arabica::DOM::Node<std::string> source = getSourceState(transition); -#if VERBOSE - std::cout << "Source States: " << ATTR(source, "id") << std::endl; -#endif - assert(source); - - bool allDescendants = true; - for (int j = 0; j < tStates.size(); j++) { - if (!isDescendant(tStates[j], source)) { - allDescendants = false; - break; - } - } - if (boost::iequals(transitionType, "internal") && - isCompound(source) && - allDescendants) { - ancestor = source; - } else { - NodeSet<std::string> tmpStates; - tmpStates.push_back(source); - tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end()); - - ancestor = findLCCA(tmpStates); - } - -#if VERBOSE - std::cout << "Ancestor: " << ATTR(ancestor, "id") << std::endl; -#endif - - for (int j = 0; j < tStates.size(); j++) { - addStatesToEnter(tStates[j], statesToEnter, statesForDefaultEntry); - } - -#if VERBOSE - std::cout << "States to enter: "; - for (int i = 0; i < statesToEnter.size(); i++) { - std::cout << LOCALNAME(statesToEnter[i]) << ":" << ATTR(statesToEnter[i], "id") << ", "; - } - std::cout << std::endl; -#endif - - for (int j = 0; j < tStates.size(); j++) { - NodeSet<std::string> ancestors = getProperAncestors(tStates[j], ancestor); - -#if VERBOSE - std::cout << "Proper Ancestors of " << ATTR(tStates[j], "id") << " and " << ATTR(ancestor, "id") << ": "; - for (int i = 0; i < ancestors.size(); i++) { - std::cout << ATTR(ancestors[i], "id") << ", "; - } - std::cout << std::endl; -#endif - - for (int k = 0; k < ancestors.size(); k++) { - statesToEnter.push_back(ancestors[k]); - if(isParallel(ancestors[k])) { - NodeSet<std::string> childs = getChildStates(ancestors[k]); - for (int l = 0; l < childs.size(); l++) { - bool someIsDescendant = false; - for (int m = 0; m < statesToEnter.size(); m++) { - if (isDescendant(statesToEnter[m], childs[l])) { - someIsDescendant = true; - break; - } - } - if (!someIsDescendant) { - addStatesToEnter(childs[l], statesToEnter, statesForDefaultEntry); - } - } - } - } - } - } - } - statesToEnter.to_document_order(); - - monIter = _monitors.begin(); - while(monIter != _monitors.end()) { - try { - (*monIter)->beforeEnteringStates(this, statesToEnter); - } catch (Event e) { - LOG(ERROR) << "Syntax error when calling beforeEnteringStates on monitors: " << std::endl << e << std::endl; - } catch (...) { - LOG(ERROR) << "An exception occured when calling beforeEnteringStates on monitors"; - } - monIter++; - } - - for (int i = 0; i < statesToEnter.size(); i++) { - Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)statesToEnter[i]; - _configuration.push_back(stateElem); - _statesToInvoke.push_back(stateElem); - if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) { - NodeSet<std::string> dataModelElems = filterChildElements(_xmlNSPrefix + "datamodel", stateElem); - if(dataModelElems.size() > 0 && _dataModel) { - Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_xmlNSPrefix + "data", dataModelElems[0]); - for (int j = 0; j < dataElems.size(); j++) { - initializeData(dataElems[j]); - } - } - stateElem.setAttribute("isFirstEntry", ""); - } - // execute onentry executable content - NodeSet<std::string> onEntryElems = filterChildElements(_xmlNSPrefix + "onEntry", stateElem); - executeContent(onEntryElems); - - if (isMember(stateElem, statesForDefaultEntry)) { - // execute initial transition content for compund states - Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", stateElem).asNodeSet(); - for (int j = 0; j < transitions.size(); j++) { - executeContent(transitions[j]); - } - } - - if (isFinal(stateElem)) { - internalDoneSend(stateElem); - Arabica::DOM::Element<std::string> parent = (Arabica::DOM::Element<std::string>)stateElem.getParentNode(); - - if (isParallel(parent.getParentNode())) { - Arabica::DOM::Element<std::string> grandParent = (Arabica::DOM::Element<std::string>)parent.getParentNode(); - - Arabica::XPath::NodeSet<std::string> childs = getChildStates(grandParent); - bool inFinalState = true; - for (int j = 0; j < childs.size(); j++) { - if (!isInFinalState(childs[j])) { - inFinalState = false; - break; - } - } - if (inFinalState) { - internalDoneSend(parent); - } - } - } - } - for (int i = 0; i < _configuration.size(); i++) { - Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)_configuration[i]; - if (isFinal(stateElem) && parentIsScxmlState(stateElem)) { - _running = false; - _done = true; - } - } - - monIter = _monitors.begin(); - while(monIter != _monitors.end()) { - try { - (*monIter)->afterEnteringStates(this); - } catch (Event e) { - LOG(ERROR) << "Syntax error when calling afterEnteringStates on monitors: " << std::endl << e << std::endl; - } catch (...) { - LOG(ERROR) << "An exception occured when calling afterEnteringStates on monitors"; - } - monIter++; - } - -} - -void Interpreter::addStatesToEnter(const Arabica::DOM::Node<std::string>& state, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) { - std::string stateId = ((Arabica::DOM::Element<std::string>)state).getAttribute("id"); - -#if VERBOSE - std::cout << "Adding state to enter: " << stateId << std::endl; -#endif - if (isHistory(state)) { - if (_historyValue.find(stateId) != _historyValue.end()) { - Arabica::XPath::NodeSet<std::string> historyValue = _historyValue[stateId]; - -#if VERBOSE - std::cout << "History State " << ATTR(state, "id") << ": "; - for (int i = 0; i < historyValue.size(); i++) { - std::cout << ATTR(historyValue[i], "id") << ", "; - } - std::cout << std::endl; -#endif - - for (int i = 0; i < historyValue.size(); i++) { - addStatesToEnter(historyValue[i], statesToEnter, statesForDefaultEntry); - NodeSet<std::string> ancestors = getProperAncestors(historyValue[i], state); - -#if VERBOSE - std::cout << "Proper Ancestors: "; - for (int i = 0; i < ancestors.size(); i++) { - std::cout << ATTR(ancestors[i], "id") << ", "; - } - std::cout << std::endl; -#endif - - for (int j = 0; j < ancestors.size(); j++) { - statesToEnter.push_back(ancestors[j]); - } - } - } else { - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", state); - for (int i = 0; i < transitions.size(); i++) { - NodeSet<std::string> targets = getTargetStates(transitions[i]); - for (int j = 0; j < targets.size(); j++) { - addStatesToEnter(targets[j], statesToEnter, statesForDefaultEntry); - - // Modifications from chris nuernberger - NodeSet<std::string> ancestors = getProperAncestors(targets[j], state); - for (int k = 0; k < ancestors.size(); k++) { - statesToEnter.push_back(ancestors[k]); - } - } - } - } - } else { - statesToEnter.push_back(state); - if (isCompound(state)) { - statesForDefaultEntry.push_back(state); - - addStatesToEnter(getInitialState(state), statesToEnter, statesForDefaultEntry); - -# if 0 - NodeSet<std::string> tStates = getTargetStates(getInitialState(state)); - for (int i = 0; i < tStates.size(); i++) { - addStatesToEnter(tStates[i], statesToEnter, statesForDefaultEntry); - } -# endif - // addStatesToEnter(getInitialState(state), statesToEnter, statesForDefaultEntry); - // NodeSet<std::string> tStates = getTargetStates(getInitialState(state)); - - } else if(isParallel(state)) { - NodeSet<std::string> childStates = getChildStates(state); - for (int i = 0; i < childStates.size(); i++) { - addStatesToEnter(childStates[i], statesToEnter, statesForDefaultEntry); - } - } - } -} -#endif - -#ifdef ENTERSTATES_02_2013 -void Interpreter::enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { - NodeSet<std::string> statesToEnter; - NodeSet<std::string> statesForDefaultEntry; - std::set<InterpreterMonitor*>::iterator monIter; - - computeEntrySet(enabledTransitions, statesToEnter, statesForDefaultEntry); - statesToEnter.sort(); // entry order is document order - for (int i = 0; i < statesToEnter.size(); i++) { - Arabica::DOM::Element<std::string> s = (Arabica::DOM::Element<std::string>)statesToEnter[i]; - _configuration.push_back(s); - _statesToInvoke.push_back(s); - - if (_binding == LATE && ATTR(s, "isFirstEntry").size() > 0) { - NodeSet<std::string> dataModelElems = filterChildElements(_xmlNSPrefix + "datamodel", s); - if(dataModelElems.size() > 0 && _dataModel) { - Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_xmlNSPrefix + "data", dataModelElems[0]); - for (int j = 0; j < dataElems.size(); j++) { - initializeData(dataElems[j]); - } - } - s.setAttribute("isFirstEntry", ""); - } - executeContent(filterChildElements(_xmlNSPrefix + "onEntry", s)); - if (isMember(s, statesForDefaultEntry)) { - executeContent(getInitialState(s)); // TODO: This part is unclear - } - -#if VERBOSE - std::cout << "Is state " << ATTR(s, "id") << " final?"; -#endif - if (isFinal(s)) { - if (parentIsScxmlState(s)) { - _running = false; - _done = true; - } else { - Arabica::DOM::Element<std::string> parent = (Arabica::DOM::Element<std::string>)s.getParentNode(); - Arabica::DOM::Element<std::string> grandParent = (Arabica::DOM::Element<std::string>)parent.getParentNode(); - internalDoneSend(parent); - - if (isParallel(grandParent)) { - Arabica::XPath::NodeSet<std::string> childs = getChildStates(grandParent); - bool inFinalState = true; - for (int j = 0; j < childs.size(); j++) { - if (!isInFinalState(childs[j])) { - inFinalState = false; - break; - } - } - if (inFinalState) { - internalDoneSend(grandParent); - } - } - } - } - } -} -void Interpreter::computeEntrySet(const Arabica::XPath::NodeSet<std::string>& transitions, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) { - for (int i = 0; i < transitions.size(); i++) { - NodeSet<std::string> targets = getTargetStates(transitions[i]); - for (int j = 0; j < targets.size(); j++) { - statesToEnter.push_back(targets[i]); - } - } - for (int i = 0; i < transitions.size(); i++) { - Arabica::DOM::Node<std::string> ancestor = getTransitionDomain(transitions[i]); - NodeSet<std::string> targets = getTargetStates(transitions[i]); - for (int j = 0; j < targets.size(); j++) { - addAncestorStatesToEnter(targets[j], ancestor, statesToEnter, statesForDefaultEntry); - } - } -} -void Interpreter::addDescendentStatesToEnter(const Arabica::DOM::Node<std::string>& state, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) { - if (isHistory(state)) { - if (_historyValue.find(ATTR(state, "id")) != _historyValue.end()) { - Arabica::XPath::NodeSet<std::string> history = _historyValue[ATTR(state, "id")]; - for (int i = 0; i < history.size(); i++) { - addDescendentStatesToEnter(history[i], statesToEnter, statesForDefaultEntry); - addAncestorStatesToEnter(history[i], state.getParentNode(), statesToEnter, statesForDefaultEntry); - } - } else { - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", state); - for (int i = 0; i < transitions.size(); i++) { - NodeSet<std::string> targets = getTargetStates(transitions[i]); - for (int j = 0; j < targets.size(); j++) { - addDescendentStatesToEnter(targets[j],statesToEnter,statesForDefaultEntry); - addAncestorStatesToEnter(targets[j], state.getParentNode(), statesToEnter, statesForDefaultEntry); - } - } - } - } else { - statesToEnter.push_back(state); - if (isCompound(state)) { - statesForDefaultEntry.push_back(state); - Node<std::string> initial = getInitialState(state); - addDescendentStatesToEnter(initial, statesToEnter, statesForDefaultEntry); - addAncestorStatesToEnter(initial, state.getParentNode(), statesToEnter, statesForDefaultEntry); - } else if (isParallel(state)) { - NodeSet<std::string> childs = getChildStates(state); - for (int i = 0; i < childs.size(); i++) { - bool someAreDescendants = false; - for (int j = 0; i < statesToEnter.size(); j++) { - if (isDescendant(statesToEnter[j], childs[i])) - someAreDescendants = true; - } - if (!someAreDescendants) { - addDescendentStatesToEnter(childs[i], statesToEnter, statesForDefaultEntry); - } - } - } - } -} - -void Interpreter::addAncestorStatesToEnter(const Arabica::DOM::Node<std::string>& state, - const Arabica::DOM::Node<std::string>& ancestor, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) { - NodeSet<std::string> properAncs = getProperAncestors(state, ancestor); - for (int k = 0; k < properAncs.size(); k++) { - statesToEnter.push_back(properAncs[k]); - if (isParallel(properAncs[k])) { - NodeSet<std::string> childs = getChildStates(properAncs[k]); - for (int i = 0; i < childs.size(); i++) { - bool someAreDescendants = false; - for (int j = 0; i < statesToEnter.size(); j++) { - if (isDescendant(statesToEnter[j], childs[i])) - someAreDescendants = true; - } - if (!someAreDescendants) { - addDescendentStatesToEnter(childs[i], statesToEnter, statesForDefaultEntry); - } - } - } - } -} - -Arabica::DOM::Node<std::string> Interpreter::getTransitionDomain(const Arabica::DOM::Node<std::string>& transition) { - Arabica::DOM::Node<std::string> source = getSourceState(transition); - if (isTargetless(transition)) { - return source; - } - - Arabica::XPath::NodeSet<std::string> targets = getTargetStates(transition); - if (boost::iequals(ATTR(transition, "type"), "internal") && isCompound(source)) { - bool allDescendants = true; - for (int i = 0; i < targets.size(); i++) { - if (!isDescendant(targets[i], source)) { - allDescendants = false; - break; - } - } - if (allDescendants) - return source; - } - - targets.push_back(source); - return findLCCA(targets); -} - -#endif - bool Interpreter::parentIsScxmlState(Arabica::DOM::Node<std::string> state) { Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state; Arabica::DOM::Element<std::string> parentElem = (Arabica::DOM::Element<std::string>)state.getParentNode(); @@ -2253,6 +1150,16 @@ NEXT_ANCESTOR: return ancestor; } +Arabica::XPath::NodeSet<std::string> Interpreter::getStates(const std::vector<std::string>& stateIds) { + Arabica::XPath::NodeSet<std::string> states; + std::vector<std::string>::const_iterator tokenIter = stateIds.begin(); + while(tokenIter != stateIds.end()) { + states.push_back(getState(*tokenIter)); + tokenIter++; + } + return states; +} + Arabica::DOM::Node<std::string> Interpreter::getState(const std::string& stateId) { if (_cachedStates.find(stateId) != _cachedStates.end()) { @@ -2304,7 +1211,7 @@ Arabica::DOM::Node<std::string> Interpreter::getSourceState(const Arabica::DOM:: * attribute nor an <initial> element is specified, the SCXML Processor must use * the first child state in document order as the default initial state. */ -Arabica::DOM::Node<std::string> Interpreter::getInitialState(Arabica::DOM::Node<std::string> state) { +Arabica::XPath::NodeSet<std::string> Interpreter::getInitialStates(Arabica::DOM::Node<std::string> state) { if (!state) { state = _document.getFirstChild(); while(state && !isState(state)) @@ -2317,25 +1224,34 @@ Arabica::DOM::Node<std::string> Interpreter::getInitialState(Arabica::DOM::Node< assert(isCompound(state) || isParallel(state)); + Arabica::XPath::NodeSet<std::string> initialStates; + // initial attribute at element Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state; if (stateElem.hasAttribute("initial")) { - return getState(stateElem.getAttribute("initial")); + return getStates(tokenizeIdRefs(stateElem.getAttribute("initial"))); } + Arabica::XPath::NodeSet<std::string> initStates; + // initial element as child - but not the implicit generated one - NodeSet<std::string> initialStates = filterChildElements(_xmlNSPrefix + "initial", state); - if(initialStates.size() == 1 && !boost::iequals(ATTR(initialStates[0], "generated"), "true")) - return initialStates[0]; + NodeSet<std::string> initElems = filterChildElements(_xmlNSPrefix + "initial", state); + if(initElems.size() == 1 && !boost::iequals(ATTR(initElems[0], "generated"), "true")) { + initStates.push_back(initialStates[0]); + return initStates; + } // first child state NodeList<std::string> childs = state.getChildNodes(); for (int i = 0; i < childs.getLength(); i++) { - if (isState(childs.item(i))) - return childs.item(i); + if (isState(childs.item(i))) { + initStates.push_back(childs.item(i)); + return initStates; + } + } // nothing found - return Arabica::DOM::Node<std::string>(); + return Arabica::XPath::NodeSet<std::string>(); } NodeSet<std::string> Interpreter::getTargetStates(const Arabica::DOM::Node<std::string>& transition) { @@ -2488,7 +1404,7 @@ bool Interpreter::isInitial(const Arabica::DOM::Node<std::string>& state) { if (!isState(parent)) return true; // scxml element - if (getInitialState(parent) == state) + if (isMember(state, getInitialStates(parent))) return true; // every nested node return false; diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index 5d29eb6..353233d 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -26,8 +26,6 @@ #include "uscxml/server/InterpreterServlet.h" -#define ORIG_ENTERSTATES - namespace uscxml { class HTTPServletInvoker; @@ -71,7 +69,16 @@ public: std::string unit; }; -class Interpreter : protected Arabica::SAX2DOM::Parser<std::string> { +class SCXMLParser : public Arabica::SAX2DOM::Parser<std::string> { +public: + SCXMLParser(Interpreter* interpreter); + void startPrefixMapping(const std::string& /* prefix */, const std::string& /* uri */); + + Arabica::SAX::CatchErrorHandler<std::string> _errorHandler; + Interpreter* _interpreter; +}; + +class Interpreter { public: enum Binding { EARLY = 0, @@ -91,8 +98,6 @@ public: static Interpreter* fromURI(const std::string& uri); static Interpreter* fromInputSource(Arabica::SAX::InputSource<std::string>& source); - virtual void startPrefixMapping(const std::string& /* prefix */, const std::string& /* uri */); - void start(); static void run(void*); void join() { @@ -102,7 +107,7 @@ public: return _running || !_done; } - void interpret(); + virtual void interpret() = 0; void addMonitor(InterpreterMonitor* monitor) { _monitors.insert(monitor); @@ -168,7 +173,13 @@ public: Arabica::XPath::NodeSet<std::string> getConfiguration() { return _configuration; } + void setConfiguration(const std::vector<std::string>& states) { + _userDefinedStartConfiguration = states; + } + Arabica::DOM::Node<std::string> getState(const std::string& stateId); + Arabica::XPath::NodeSet<std::string> getStates(const std::vector<std::string>& stateIds); + Arabica::DOM::Document<std::string>& getDocument() { return _document; } @@ -203,13 +214,18 @@ public: static bool isCompound(const Arabica::DOM::Node<std::string>& state); static bool isDescendant(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2); + static std::vector<std::string> tokenizeIdRefs(const std::string& idRefs); + bool isInitial(const Arabica::DOM::Node<std::string>& state); - Arabica::DOM::Node<std::string> getInitialState(Arabica::DOM::Node<std::string> state = Arabica::DOM::Node<std::string>()); + Arabica::XPath::NodeSet<std::string> getInitialStates(Arabica::DOM::Node<std::string> state = Arabica::DOM::Node<std::string>()); static Arabica::XPath::NodeSet<std::string> getChildStates(const Arabica::DOM::Node<std::string>& state); Arabica::XPath::NodeSet<std::string> getTargetStates(const Arabica::DOM::Node<std::string>& transition); + Arabica::DOM::Node<std::string> getSourceState(const Arabica::DOM::Node<std::string>& transition); static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagname, const Arabica::DOM::Node<std::string>& node); static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagName, const Arabica::XPath::NodeSet<std::string>& nodeSet); + Arabica::DOM::Node<std::string> findLCCA(const Arabica::XPath::NodeSet<std::string>& states); + Arabica::XPath::NodeSet<std::string> getProperAncestors(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2); static const std::string getUUID(); protected: @@ -219,8 +235,6 @@ protected: void normalize(const Arabica::DOM::Document<std::string>& node); void setupIOProcessors(); - void mainEventLoop(); - bool _stable; tthread::thread* _thread; tthread::mutex _mutex; @@ -241,7 +255,8 @@ protected: Binding _binding; Arabica::XPath::NodeSet<std::string> _configuration; Arabica::XPath::NodeSet<std::string> _statesToInvoke; - + std::vector<std::string> _userDefinedStartConfiguration; + DataModel _dataModel; std::map<std::string, Arabica::XPath::NodeSet<std::string> > _historyValue; @@ -251,52 +266,14 @@ protected: DelayedEventQueue* _sendQueue; Event _currEvent; - InterpreterServlet* _httpServlet; - std::set<InterpreterMonitor*> _monitors; static URL toBaseURI(const URL& url); - void microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); - void executeTransitionContent(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); void executeContent(const Arabica::DOM::Node<std::string>& content); void executeContent(const Arabica::DOM::NodeList<std::string>& content); void executeContent(const Arabica::XPath::NodeSet<std::string>& content); - void initializeData(const Arabica::DOM::Node<std::string>& data); - void exitInterpreter(); - -#ifdef ORIG_ENTERSTATES - void enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); - void addStatesToEnter(const Arabica::DOM::Node<std::string>& state, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry); -#endif - -#ifdef ENTERSTATES_02_2013 - void enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); - void computeEntrySet(const Arabica::XPath::NodeSet<std::string>& transitions, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry); - void addDescendentStatesToEnter(const Arabica::DOM::Node<std::string>& state, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry); - void addAncestorStatesToEnter(const Arabica::DOM::Node<std::string>& state, - const Arabica::DOM::Node<std::string>& ancestor, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry); - Arabica::DOM::Node<std::string> getTransitionDomain(const Arabica::DOM::Node<std::string>& transition); - -#endif - - void exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); - - Arabica::XPath::NodeSet<std::string> selectEventlessTransitions(); - Arabica::XPath::NodeSet<std::string> selectTransitions(const std::string& event); - Arabica::DOM::Node<std::string> getSourceState(const Arabica::DOM::Node<std::string>& transition); - Arabica::DOM::Node<std::string> findLCCA(const Arabica::XPath::NodeSet<std::string>& states); - Arabica::XPath::NodeSet<std::string> getProperAncestors(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2); - void send(const Arabica::DOM::Node<std::string>& element); void invoke(const Arabica::DOM::Node<std::string>& element); @@ -306,16 +283,11 @@ protected: static void delayedSend(void* userdata, std::string eventName); static bool nameMatch(const std::string& transitionEvent, const std::string& event); - Arabica::XPath::NodeSet<std::string> filterPreempted(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); - bool isPreemptingTransition(const Arabica::DOM::Node<std::string>& t1, const Arabica::DOM::Node<std::string>& t2); bool isWithinSameChild(const Arabica::DOM::Node<std::string>& transition); bool hasConditionMatch(const Arabica::DOM::Node<std::string>& conditional); bool isInFinalState(const Arabica::DOM::Node<std::string>& state); bool parentIsScxmlState(Arabica::DOM::Node<std::string> state); -// Arabica::DOM::Node<std::string> getTransitionSubgraph(const Arabica::DOM::Node<std::string>& transition); - - static std::vector<std::string> tokenizeIdRefs(const std::string& idRefs); static boost::uuids::random_generator uuidGen; @@ -327,7 +299,6 @@ protected: Data _cmdLineOptions; IOProcessor getIOProcessor(const std::string& type); -// IOProcessor* getIOProcessorForId(const std::string& sendId); std::map<std::string, IOProcessor> _ioProcessors; std::map<std::string, std::pair<Interpreter*, SendRequest> > _sendIds; @@ -335,9 +306,11 @@ protected: std::map<std::string, Invoker> _autoForwardees; std::map<Arabica::DOM::Node<std::string>, ExecutableContent> _executableContent; - /// We need to remember to adapt them when the DOM is operated upon + /// TODO: We need to remember to adapt them when the DOM is operated upon std::map<std::string, Arabica::DOM::Node<std::string> > _cachedStates; std::map<std::string, URL> _cachedURLs; + + friend class SCXMLParser; }; } diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp index 13b0b55..845118b 100644 --- a/src/uscxml/Message.cpp +++ b/src/uscxml/Message.cpp @@ -179,6 +179,10 @@ Data Data::fromXML(const std::string& xmlString) { Data Data::fromJSON(const std::string& jsonString) { Data data; + + if (jsonString.length() == 0) + return data; + jsmn_parser p; jsmntok_t* t = NULL; diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp new file mode 100644 index 0000000..d95ae4c --- /dev/null +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -0,0 +1,920 @@ +#include "InterpreterDraft6.h" + +#include <glog/logging.h> + +namespace uscxml { + +using namespace Arabica::XPath; +using namespace Arabica::DOM; + +// see: http://www.w3.org/TR/scxml/#AlgorithmforSCXMLInterpretation +void InterpreterDraft6::interpret() { + if (!_isInitialized) + init(); + + if (!_scxml) + return; +// dump(); + + _sessionId = getUUID(); + + std::string datamodelName; + if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "datamodel")) + datamodelName = ATTR(_scxml, "datamodel"); + if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "profile")) // SCION SCXML uses profile to specify datamodel + datamodelName = ATTR(_scxml, "profile"); + if(datamodelName.length() > 0) + _dataModel = Factory::createDataModel(datamodelName, this); + if(datamodelName.length() > 0 && !_dataModel) { + LOG(ERROR) << "No datamodel for " << datamodelName << " registered"; + } + + if (_dataModel) { + _dataModel.assign("_x.args", _cmdLineOptions); + if (_httpServlet) { + Data data; + data.compound["location"] = Data(_httpServlet->getURL(), Data::VERBATIM); + _dataModel.assign("_ioprocessors['http']", data); + } + } + + setupIOProcessors(); + + _running = true; + _binding = (HAS_ATTR(_scxml, "binding") && boost::iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); + + // @TODO: Reread http://www.w3.org/TR/scxml/#DataBinding + + if (_dataModel && _binding == EARLY) { + // initialize all data elements + NodeSet<std::string> dataElems = _xpath.evaluate("//" + _xpathPrefix + "data", _document).asNodeSet(); + for (unsigned int i = 0; i < dataElems.size(); i++) { + initializeData(dataElems[i]); + } + } else if(_dataModel) { + // initialize current data elements + NodeSet<std::string> topDataElems = filterChildElements(_xmlNSPrefix + "data", filterChildElements(_xmlNSPrefix + "datamodel", _scxml)); + for (unsigned int i = 0; i < topDataElems.size(); i++) { + initializeData(topDataElems[i]); + } + } + + // executeGlobalScriptElements + NodeSet<std::string> globalScriptElems = _xpath.evaluate("/" + _xpathPrefix + "scxml/" + _xpathPrefix + "script", _document).asNodeSet(); + for (unsigned int i = 0; i < globalScriptElems.size(); i++) { + if (_dataModel) + executeContent(globalScriptElems[i]); + } + + NodeSet<std::string> initialTransitions; + + if (_userDefinedStartConfiguration.size() == 0) { + // try to get initial transition form initial element + initialTransitions = _xpath.evaluate("/" + _xpathPrefix + "scxml/" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", _document).asNodeSet(); + } + + if (initialTransitions.size() == 0) { + Arabica::XPath::NodeSet<std::string> initialStates; + if (_userDefinedStartConfiguration.size() > 0) { + // otherwise use user supplied config + initialTransitions = getStates(_userDefinedStartConfiguration); + } else { + // or fetch per draft + initialStates = getInitialStates(); + } + + assert(initialStates.size() > 0); + for (int i = 0; i < initialStates.size(); i++) { + Arabica::DOM::Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial"); + initialElem.setAttribute("generated", "true"); + Arabica::DOM::Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition"); + transitionElem.setAttribute("target", ATTR(initialStates[i], "id")); + initialElem.appendChild(transitionElem); + _scxml.appendChild(initialElem); + initialTransitions.push_back(transitionElem); + } + } + + assert(initialTransitions.size() > 0); + enterStates(initialTransitions); + + assert(hasLegalConfiguration()); + mainEventLoop(); + + if (_parentQueue) { + // send one final event to unblock eventual listeners + Event quit; + quit.name = "done.state.scxml"; + _parentQueue->push(quit); + } + + // set datamodel to null from this thread + if(_dataModel) + _dataModel = DataModel(); + +} + +/** + * Called with a single data element from the topmost datamodel element. + */ +void InterpreterDraft6::initializeData(const Arabica::DOM::Node<std::string>& data) { + if (!_dataModel) { + LOG(ERROR) << "Cannot initialize data when no datamodel is given!"; + return; + } + try { + if (!HAS_ATTR(data, "id")) { + LOG(ERROR) << "Data element has no id!"; + return; + } + + if (HAS_ATTR(data, "expr")) { + std::string value = ATTR(data, "expr"); + _dataModel.assign(ATTR(data, "id"), value); + } else if (HAS_ATTR(data, "src")) { + URL srcURL(ATTR(data, "src")); + if (!srcURL.isAbsolute()) + toAbsoluteURI(srcURL); + + std::stringstream ss; + if (_cachedURLs.find(srcURL.asString()) != _cachedURLs.end()) { + ss << _cachedURLs[srcURL.asString()]; + } else { + ss << srcURL; + _cachedURLs[srcURL.asString()] = srcURL; + } + _dataModel.assign(ATTR(data, "id"), ss.str()); + + } else if (data.hasChildNodes()) { + // search for the text node with the actual script + NodeList<std::string> dataChilds = data.getChildNodes(); + for (int i = 0; i < dataChilds.getLength(); i++) { + if (dataChilds.item(i).getNodeType() == Node_base::TEXT_NODE) { + Data value = Data(dataChilds.item(i).getNodeValue()); + _dataModel.assign(ATTR(data, "id"), value); + break; + } + } + } + + } catch (Event e) { + LOG(ERROR) << "Syntax error in data element:" << std::endl << e << std::endl; + } +} + +void InterpreterDraft6::mainEventLoop() { + std::set<InterpreterMonitor*>::iterator monIter; + + while(_running) { + NodeSet<std::string> enabledTransitions; + _stable = false; + + // Here we handle eventless transitions and transitions + // triggered by internal events until machine is stable + while(_running && !_stable) { +#if 0 + std::cout << "Configuration: "; + for (int i = 0; i < _configuration.size(); i++) { + std::cout << ATTR(_configuration[i], "id") << ", "; + } + std::cout << std::endl; +#endif + monIter = _monitors.begin(); + while(monIter != _monitors.end()) { + try { + (*monIter)->beforeMicroStep(this); + } catch (Event e) { + LOG(ERROR) << "Syntax error when calling beforeMicroStep on monitors: " << std::endl << e << std::endl; + } catch (...) { + LOG(ERROR) << "An exception occured when calling beforeMicroStep on monitors"; + } + monIter++; + } + + enabledTransitions = selectEventlessTransitions(); + if (enabledTransitions.size() == 0) { + if (_internalQueue.size() == 0) { + _stable = true; + } else { + _currEvent = _internalQueue.front(); + _internalQueue.pop_front(); +#if VERBOSE + std::cout << "Received internal event " << _currEvent.name << std::endl; +#endif + if (_dataModel) + _dataModel.setEvent(_currEvent); + enabledTransitions = selectTransitions(_currEvent.name); + } + } + if (!enabledTransitions.empty()) { + monIter = _monitors.begin(); + while(monIter != _monitors.end()) { + try { + (*monIter)->beforeTakingTransitions(this, enabledTransitions); + } catch (Event e) { + LOG(ERROR) << "Syntax error when calling beforeTakingTransitions on monitors: " << std::endl << e << std::endl; + } catch (...) { + LOG(ERROR) << "An exception occured when calling beforeTakingTransitions on monitors"; + } + monIter++; + } + microstep(enabledTransitions); + } + } + + for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { + NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _statesToInvoke[i]); + for (unsigned int j = 0; j < invokes.size(); j++) { + invoke(invokes[j]); + } + } + + _statesToInvoke = NodeSet<std::string>(); + if (!_internalQueue.empty()) + continue; + + // assume that we have a legal configuration as soon as the internal queue is empty + assert(hasLegalConfiguration()); + + monIter = _monitors.begin(); +// if (!_sendQueue || _sendQueue->isEmpty()) { + while(monIter != _monitors.end()) { + try { + (*monIter)->onStableConfiguration(this); + } catch (Event e) { + LOG(ERROR) << "Syntax error when calling onStableConfiguration on monitors: " << std::endl << e << std::endl; + } catch (...) { + LOG(ERROR) << "An exception occured when calling onStableConfiguration on monitors"; + } + monIter++; + } +// } + + // whenever we have a stable configuration, run the mainThread hooks with 200fps + while(_externalQueue.isEmpty() && _thread == NULL) { + runOnMainThread(200); + } + + _currEvent = _externalQueue.pop(); +#if VERBOSE + std::cout << "Received externalEvent event " << _currEvent.name << std::endl; +#endif + _currEvent.type = Event::EXTERNAL; // make sure it is set to external + if (!_running) + exitInterpreter(); + + if (_dataModel && boost::iequals(_currEvent.name, "cancel.invoke." + _sessionId)) + break; + + if (_dataModel) + try { + _dataModel.setEvent(_currEvent); + } catch (Event e) { + LOG(ERROR) << "Syntax error while setting external event:" << std::endl << e << std::endl; + } + for (unsigned int i = 0; i < _configuration.size(); i++) { + NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _configuration[i]); + for (unsigned int j = 0; j < invokes.size(); j++) { + Arabica::DOM::Element<std::string> invokeElem = (Arabica::DOM::Element<std::string>)invokes[j]; + std::string invokeId; + if (HAS_ATTR(invokeElem, "id")) + invokeId = ATTR(invokeElem, "id"); + if (HAS_ATTR(invokeElem, "idlocation") && _dataModel) + invokeId = _dataModel.evalAsString(ATTR(invokeElem, "idlocation")); + + std::string autoForward = invokeElem.getAttribute("autoforward"); + if (boost::iequals(invokeId, _currEvent.invokeid)) { + + Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_xmlNSPrefix + "finalize", invokeElem); + for (int k = 0; k < finalizes.size(); k++) { + Arabica::DOM::Element<std::string> finalizeElem = Arabica::DOM::Element<std::string>(finalizes[k]); + executeContent(finalizeElem); + } + + } + if (boost::iequals(autoForward, "true")) { + try { + _invokers[invokeId].send(_currEvent); + } catch(...) { + LOG(ERROR) << "Exception caught while sending event to invoker " << invokeId; + } + } + } + } + enabledTransitions = selectTransitions(_currEvent.name); + if (!enabledTransitions.empty()) + microstep(enabledTransitions); + } + monIter = _monitors.begin(); + while(monIter != _monitors.end()) { + try { + (*monIter)->beforeCompletion(this); + } catch (Event e) { + LOG(ERROR) << "Syntax error when calling beforeCompletion on monitors: " << std::endl << e << std::endl; + } catch (...) { + LOG(ERROR) << "An exception occured when calling beforeCompletion on monitors"; + } + monIter++; + } + + exitInterpreter(); + + monIter = _monitors.begin(); + while(monIter != _monitors.end()) { + try { + (*monIter)->afterCompletion(this); + } catch (Event e) { + LOG(ERROR) << "Syntax error when calling afterCompletion on monitors: " << std::endl << e << std::endl; + } catch (...) { + LOG(ERROR) << "An exception occured when calling afterCompletion on monitors"; + } + monIter++; + } + +} + +Arabica::XPath::NodeSet<std::string> InterpreterDraft6::selectTransitions(const std::string& event) { + Arabica::XPath::NodeSet<std::string> enabledTransitions; + + NodeSet<std::string> atomicStates; + for (unsigned int i = 0; i < _configuration.size(); i++) { + if (isAtomic(_configuration[i])) + atomicStates.push_back(_configuration[i]); + } + atomicStates.to_document_order(); + + for (unsigned int i = 0; i < atomicStates.size(); i++) { + NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>()); + + NodeSet<std::string> sortedAncestors; + sortedAncestors.push_back(atomicStates[i]); + sortedAncestors.insert(sortedAncestors.end(), ancestors.begin(), ancestors.end()); + + for (unsigned int j = 0; j < sortedAncestors.size(); j++) { + NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", sortedAncestors[j]); + for (unsigned int k = 0; k < transitions.size(); k++) { + std::string eventName; + if (HAS_ATTR(transitions[k], "event")) { + eventName = ATTR(transitions[k], "event"); + } else if(HAS_ATTR(transitions[k], "eventexpr")) { + if (_dataModel) { + eventName = _dataModel.evalAsString(ATTR(transitions[k], "eventexpr")); + } else { + LOG(ERROR) << "Transition has eventexpr attribute with no datamodel defined"; + goto LOOP; + } + } else { + goto LOOP; + } + + if (eventName.length() > 0 && + nameMatch(eventName, event) && + hasConditionMatch(transitions[k])) { + enabledTransitions.push_back(transitions[k]); + goto LOOP; + } + } + } +LOOP: + ; + } + + enabledTransitions = filterPreempted(enabledTransitions); + return enabledTransitions; +} + +Arabica::XPath::NodeSet<std::string> InterpreterDraft6::selectEventlessTransitions() { + Arabica::XPath::NodeSet<std::string> enabledTransitions; + + NodeSet<std::string> atomicStates; + for (unsigned int i = 0; i < _configuration.size(); i++) { + if (isAtomic(_configuration[i])) + atomicStates.push_back(_configuration[i]); + } + atomicStates.to_document_order(); + + for (unsigned int i = 0; i < atomicStates.size(); i++) { + NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>()); + ancestors.push_back(atomicStates[i]); + for (unsigned int j = 0; j < ancestors.size(); j++) { + NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestors[j]); + for (unsigned int k = 0; k < transitions.size(); k++) { + if (!HAS_ATTR(transitions[k], "event") && hasConditionMatch(transitions[k])) { + enabledTransitions.push_back(transitions[k]); + goto LOOP; + } + } + +#if 0 + NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestors[j]); + for (unsigned int k = 0; k < transitions.size(); k++) { + if (!((Arabica::DOM::Element<std::string>)transitions[k]).hasAttribute("event") && hasConditionMatch(transitions[k])) { + enabledTransitions.push_back(transitions[k]); + goto LOOP; + } + } +#endif + } +LOOP: + ; + } + + enabledTransitions = filterPreempted(enabledTransitions); + return enabledTransitions; +} + +Arabica::XPath::NodeSet<std::string> InterpreterDraft6::filterPreempted(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { + Arabica::XPath::NodeSet<std::string> filteredTransitions; + for (unsigned int i = 0; i < enabledTransitions.size(); i++) { + Arabica::DOM::Node<std::string> t = enabledTransitions[i]; + for (unsigned int j = i+1; j < enabledTransitions.size(); j++) { + Arabica::DOM::Node<std::string> t2 = enabledTransitions[j]; + if (isPreemptingTransition(t2, t)) { +#if VERBOSE + std::cout << "Transition preempted!: " << std::endl << t2 << std::endl << t << std::endl; +#endif + goto LOOP; + } + } + filteredTransitions.push_back(t); +LOOP: + ; + } + return filteredTransitions; +} + +bool InterpreterDraft6::isPreemptingTransition(const Arabica::DOM::Node<std::string>& t1, const Arabica::DOM::Node<std::string>& t2) { + assert(t1); + assert(t2); + +#if VERBOSE + std::cout << "Checking preemption: " << std::endl << t1 << std::endl << t2 << std::endl; +#endif + +#if 1 + if (t1 == t2) + return false; + if (isWithinSameChild(t1) && (!isTargetless(t2) && !isWithinSameChild(t2))) + return true; + if (!isTargetless(t1) && !isWithinSameChild(t1)) + return true; + return false; +#endif + +} + +void InterpreterDraft6::microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { +#if 0 + std::cout << "Transitions: "; + for (int i = 0; i < enabledTransitions.size(); i++) { + std::cout << ((Arabica::DOM::Element<std::string>)getSourceState(enabledTransitions[i])).getAttribute("id") << " -> " << std::endl; + NodeSet<std::string> targetSet = getTargetStates(enabledTransitions[i]); + for (int j = 0; j < targetSet.size(); j++) { + std::cout << " " << ((Arabica::DOM::Element<std::string>)targetSet[j]).getAttribute("id") << std::endl; + } + } + std::cout << std::endl; +#endif + + exitStates(enabledTransitions); + executeContent(enabledTransitions); + enterStates(enabledTransitions); +} + +void InterpreterDraft6::exitInterpreter() { + NodeSet<std::string> statesToExit = _configuration; + statesToExit.to_document_order(); + statesToExit.reverse(); + + for (int i = 0; i < statesToExit.size(); i++) { + Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_xmlNSPrefix + "onexit", statesToExit[i]); + for (int j = 0; j < onExitElems.size(); j++) { + executeContent(onExitElems[j]); + } + Arabica::XPath::NodeSet<std::string> invokeElems = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]); + for (int j = 0; j < invokeElems.size(); j++) { + cancelInvoke(invokeElems[j]); + } + if (isFinal(statesToExit[i]) && parentIsScxmlState(statesToExit[i])) { + returnDoneEvent(statesToExit[i]); + } + } + _configuration = NodeSet<std::string>(); +} + + +void InterpreterDraft6::exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { + NodeSet<std::string> statesToExit; + std::set<InterpreterMonitor*>::iterator monIter; + +#if VERBOSE + std::cout << "Enabled exit transitions: " << std::endl; + for (int i = 0; i < enabledTransitions.size(); i++) { + std::cout << enabledTransitions[i] << std::endl; + } + std::cout << std::endl; +#endif + + for (int i = 0; i < enabledTransitions.size(); i++) { + Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]); + if (!isTargetless(transition)) { + std::string transitionType = (boost::iequals(transition.getAttribute("type"), "internal") ? "internal" : "external"); + NodeSet<std::string> tStates = getTargetStates(transition); + Arabica::DOM::Node<std::string> ancestor; + Arabica::DOM::Node<std::string> source = getSourceState(transition); + + bool allDescendants = true; + for (int j = 0; j < tStates.size(); j++) { + if (!isDescendant(tStates[j], source)) { + allDescendants = false; + break; + } + } + if (boost::iequals(transitionType, "internal") && + isCompound(source) && + allDescendants) { + ancestor = source; + } else { + NodeSet<std::string> tmpStates; + tmpStates.push_back(source); + tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end()); + +#if VERBOSE + std::cout << "tmpStates: "; + for (int i = 0; i < tmpStates.size(); i++) { + std::cout << ATTR(tmpStates[i], "id") << ", "; + } + std::cout << std::endl; +#endif + ancestor = findLCCA(tmpStates); + } + +#if VERBOSE + std::cout << "Ancestor: " << ATTR(ancestor, "id") << std::endl;; +#endif + + for (int j = 0; j < _configuration.size(); j++) { + if (isDescendant(_configuration[j], ancestor)) + statesToExit.push_back(_configuration[j]); + } + } + } + +#if VERBOSE + std::cout << "States to exit: "; + for (int i = 0; i < statesToExit.size(); i++) { + std::cout << LOCALNAME(statesToExit[i]) << ":" << ATTR(statesToExit[i], "id") << ", "; + } + std::cout << std::endl; + +#endif + + // remove statesToExit from _statesToInvoke + std::list<Arabica::DOM::Node<std::string> > tmp; + for (int i = 0; i < _statesToInvoke.size(); i++) { + if (!isMember(_statesToInvoke[i], statesToExit)) { + tmp.push_back(_statesToInvoke[i]); + } + } + _statesToInvoke = NodeSet<std::string>(); + _statesToInvoke.insert(_statesToInvoke.end(), tmp.begin(), tmp.end()); + + statesToExit.to_document_order(); + statesToExit.reverse(); + + monIter = _monitors.begin(); + while(monIter != _monitors.end()) { + try { + (*monIter)->beforeExitingStates(this, statesToExit); + } catch (Event e) { + LOG(ERROR) << "Syntax error when calling beforeExitingStates on monitors: " << std::endl << e << std::endl; + } catch (...) { + LOG(ERROR) << "An exception occured when calling beforeExitingStates on monitors"; + } + monIter++; + } + + for (int i = 0; i < statesToExit.size(); i++) { + NodeSet<std::string> histories = filterChildElements(_xmlNSPrefix + "history", statesToExit[i]); + for (int j = 0; j < histories.size(); j++) { + Arabica::DOM::Element<std::string> historyElem = (Arabica::DOM::Element<std::string>)histories[j]; + std::string historyType = (historyElem.hasAttribute("type") ? historyElem.getAttribute("type") : "shallow"); + NodeSet<std::string> historyNodes; + for (int k = 0; k < _configuration.size(); k++) { + if (boost::iequals(historyType, "deep")) { + if (isAtomic(_configuration[k]) && isDescendant(_configuration[k], statesToExit[i])) + historyNodes.push_back(_configuration[k]); + } else { + if (_configuration[k].getParentNode() == statesToExit[i]) + historyNodes.push_back(_configuration[k]); + } + } + _historyValue[historyElem.getAttribute("id")] = historyNodes; +#if 0 + std::cout << "History node " << ATTR(historyElem, "id") << " contains: "; + for (int i = 0; i < historyNodes.size(); i++) { + std::cout << ATTR(historyNodes[i], "id") << ", "; + } + std::cout << std::endl; + +#endif + + } + } + + for (int i = 0; i < statesToExit.size(); i++) { + NodeSet<std::string> onExits = filterChildElements(_xmlNSPrefix + "onExit", statesToExit[i]); + for (int j = 0; j < onExits.size(); j++) { + Arabica::DOM::Element<std::string> onExitElem = (Arabica::DOM::Element<std::string>)onExits[j]; + executeContent(onExitElem); + } + NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]); + for (int j = 0; j < invokes.size(); j++) { + Arabica::DOM::Element<std::string> invokeElem = (Arabica::DOM::Element<std::string>)invokes[j]; + cancelInvoke(invokeElem); + } + } + + // remove statesToExit from _configuration + tmp.clear(); + for (int i = 0; i < _configuration.size(); i++) { + if (!isMember(_configuration[i], statesToExit)) { + tmp.push_back(_configuration[i]); + } + } + _configuration = NodeSet<std::string>(); + _configuration.insert(_configuration.end(), tmp.begin(), tmp.end()); + + monIter = _monitors.begin(); + while(monIter != _monitors.end()) { + try { + (*monIter)->afterExitingStates(this); + } catch (Event e) { + LOG(ERROR) << "Syntax error when calling afterExitingStates on monitors: " << std::endl << e << std::endl; + } catch (...) { + LOG(ERROR) << "An exception occured when calling afterExitingStates on monitors"; + } + monIter++; + } + +} + +void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { + NodeSet<std::string> statesToEnter; + NodeSet<std::string> statesForDefaultEntry; + std::set<InterpreterMonitor*>::iterator monIter; + +#if VERBOSE + std::cout << "Enabled enter transitions: " << std::endl; + for (int i = 0; i < enabledTransitions.size(); i++) { + std::cout << enabledTransitions[i] << std::endl; + } + std::cout << std::endl; +#endif + + for (int i = 0; i < enabledTransitions.size(); i++) { + Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]); + if (!isTargetless(transition)) { + std::string transitionType = (boost::iequals(transition.getAttribute("type"), "internal") ? "internal" : "external"); + NodeSet<std::string> tStates = getTargetStates(transition); + +#if VERBOSE + std::cout << "Target States: "; + for (int i = 0; i < tStates.size(); i++) { + std::cout << ATTR(tStates[i], "id") << ", "; + } + std::cout << std::endl; +#endif + + Arabica::DOM::Node<std::string> ancestor; + Arabica::DOM::Node<std::string> source = getSourceState(transition); +#if VERBOSE + std::cout << "Source States: " << ATTR(source, "id") << std::endl; +#endif + assert(source); + + bool allDescendants = true; + for (int j = 0; j < tStates.size(); j++) { + if (!isDescendant(tStates[j], source)) { + allDescendants = false; + break; + } + } + if (boost::iequals(transitionType, "internal") && + isCompound(source) && + allDescendants) { + ancestor = source; + } else { + NodeSet<std::string> tmpStates; + tmpStates.push_back(source); + tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end()); + + ancestor = findLCCA(tmpStates); + } + +#if VERBOSE + std::cout << "Ancestor: " << ATTR(ancestor, "id") << std::endl; +#endif + + for (int j = 0; j < tStates.size(); j++) { + addStatesToEnter(tStates[j], statesToEnter, statesForDefaultEntry); + } + +#if VERBOSE + std::cout << "States to enter: "; + for (int i = 0; i < statesToEnter.size(); i++) { + std::cout << LOCALNAME(statesToEnter[i]) << ":" << ATTR(statesToEnter[i], "id") << ", "; + } + std::cout << std::endl; +#endif + + for (int j = 0; j < tStates.size(); j++) { + NodeSet<std::string> ancestors = getProperAncestors(tStates[j], ancestor); + +#if VERBOSE + std::cout << "Proper Ancestors of " << ATTR(tStates[j], "id") << " and " << ATTR(ancestor, "id") << ": "; + for (int i = 0; i < ancestors.size(); i++) { + std::cout << ATTR(ancestors[i], "id") << ", "; + } + std::cout << std::endl; +#endif + + for (int k = 0; k < ancestors.size(); k++) { + statesToEnter.push_back(ancestors[k]); + if(isParallel(ancestors[k])) { + NodeSet<std::string> childs = getChildStates(ancestors[k]); + for (int l = 0; l < childs.size(); l++) { + bool someIsDescendant = false; + for (int m = 0; m < statesToEnter.size(); m++) { + if (isDescendant(statesToEnter[m], childs[l])) { + someIsDescendant = true; + break; + } + } + if (!someIsDescendant) { + addStatesToEnter(childs[l], statesToEnter, statesForDefaultEntry); + } + } + } + } + } + } + } + statesToEnter.to_document_order(); + + monIter = _monitors.begin(); + while(monIter != _monitors.end()) { + try { + (*monIter)->beforeEnteringStates(this, statesToEnter); + } catch (Event e) { + LOG(ERROR) << "Syntax error when calling beforeEnteringStates on monitors: " << std::endl << e << std::endl; + } catch (...) { + LOG(ERROR) << "An exception occured when calling beforeEnteringStates on monitors"; + } + monIter++; + } + + for (int i = 0; i < statesToEnter.size(); i++) { + Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)statesToEnter[i]; + _configuration.push_back(stateElem); + _statesToInvoke.push_back(stateElem); + if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) { + NodeSet<std::string> dataModelElems = filterChildElements(_xmlNSPrefix + "datamodel", stateElem); + if(dataModelElems.size() > 0 && _dataModel) { + Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_xmlNSPrefix + "data", dataModelElems[0]); + for (int j = 0; j < dataElems.size(); j++) { + initializeData(dataElems[j]); + } + } + stateElem.setAttribute("isFirstEntry", ""); + } + // execute onentry executable content + NodeSet<std::string> onEntryElems = filterChildElements(_xmlNSPrefix + "onEntry", stateElem); + executeContent(onEntryElems); + + if (isMember(stateElem, statesForDefaultEntry)) { + // execute initial transition content for compund states + Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", stateElem).asNodeSet(); + for (int j = 0; j < transitions.size(); j++) { + executeContent(transitions[j]); + } + } + + if (isFinal(stateElem)) { + internalDoneSend(stateElem); + Arabica::DOM::Element<std::string> parent = (Arabica::DOM::Element<std::string>)stateElem.getParentNode(); + + if (isParallel(parent.getParentNode())) { + Arabica::DOM::Element<std::string> grandParent = (Arabica::DOM::Element<std::string>)parent.getParentNode(); + + Arabica::XPath::NodeSet<std::string> childs = getChildStates(grandParent); + bool inFinalState = true; + for (int j = 0; j < childs.size(); j++) { + if (!isInFinalState(childs[j])) { + inFinalState = false; + break; + } + } + if (inFinalState) { + internalDoneSend(parent); + } + } + } + } + for (int i = 0; i < _configuration.size(); i++) { + Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)_configuration[i]; + if (isFinal(stateElem) && parentIsScxmlState(stateElem)) { + _running = false; + _done = true; + } + } + + monIter = _monitors.begin(); + while(monIter != _monitors.end()) { + try { + (*monIter)->afterEnteringStates(this); + } catch (Event e) { + LOG(ERROR) << "Syntax error when calling afterEnteringStates on monitors: " << std::endl << e << std::endl; + } catch (...) { + LOG(ERROR) << "An exception occured when calling afterEnteringStates on monitors"; + } + monIter++; + } + +} + +void InterpreterDraft6::addStatesToEnter(const Arabica::DOM::Node<std::string>& state, + Arabica::XPath::NodeSet<std::string>& statesToEnter, + Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) { + std::string stateId = ((Arabica::DOM::Element<std::string>)state).getAttribute("id"); + +#if VERBOSE + std::cout << "Adding state to enter: " << stateId << std::endl; +#endif + if (isHistory(state)) { + if (_historyValue.find(stateId) != _historyValue.end()) { + Arabica::XPath::NodeSet<std::string> historyValue = _historyValue[stateId]; + +#if VERBOSE + std::cout << "History State " << ATTR(state, "id") << ": "; + for (int i = 0; i < historyValue.size(); i++) { + std::cout << ATTR(historyValue[i], "id") << ", "; + } + std::cout << std::endl; +#endif + + for (int i = 0; i < historyValue.size(); i++) { + addStatesToEnter(historyValue[i], statesToEnter, statesForDefaultEntry); + NodeSet<std::string> ancestors = getProperAncestors(historyValue[i], state); + +#if VERBOSE + std::cout << "Proper Ancestors: "; + for (int i = 0; i < ancestors.size(); i++) { + std::cout << ATTR(ancestors[i], "id") << ", "; + } + std::cout << std::endl; +#endif + + for (int j = 0; j < ancestors.size(); j++) { + statesToEnter.push_back(ancestors[j]); + } + } + } else { + NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", state); + for (int i = 0; i < transitions.size(); i++) { + NodeSet<std::string> targets = getTargetStates(transitions[i]); + for (int j = 0; j < targets.size(); j++) { + addStatesToEnter(targets[j], statesToEnter, statesForDefaultEntry); + + // Modifications from chris nuernberger + NodeSet<std::string> ancestors = getProperAncestors(targets[j], state); + for (int k = 0; k < ancestors.size(); k++) { + statesToEnter.push_back(ancestors[k]); + } + } + } + } + } else { + statesToEnter.push_back(state); + if (isCompound(state)) { + statesForDefaultEntry.push_back(state); + + NodeSet<std::string> tStates = getInitialStates(state); + for (int i = 0; i < tStates.size(); i++) { + addStatesToEnter(tStates[i], statesToEnter, statesForDefaultEntry); + } + + // addStatesToEnter(getInitialState(state), statesToEnter, statesForDefaultEntry); + // NodeSet<std::string> tStates = getTargetStates(getInitialState(state)); + + } else if(isParallel(state)) { + NodeSet<std::string> childStates = getChildStates(state); + for (int i = 0; i < childStates.size(); i++) { + addStatesToEnter(childStates[i], statesToEnter, statesForDefaultEntry); + } + } + } +} + + +}
\ No newline at end of file diff --git a/src/uscxml/interpreter/InterpreterDraft6.h b/src/uscxml/interpreter/InterpreterDraft6.h new file mode 100644 index 0000000..10ff10a --- /dev/null +++ b/src/uscxml/interpreter/InterpreterDraft6.h @@ -0,0 +1,31 @@ +#ifndef INTERPRETERDRAFT6_H_JAXK9FE1 +#define INTERPRETERDRAFT6_H_JAXK9FE1 + +#include "uscxml/Interpreter.h" + +namespace uscxml { + +class InterpreterDraft6 : public Interpreter { + void interpret(); + void mainEventLoop(); + + void initializeData(const Arabica::DOM::Node<std::string>& data); + void microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); + void enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); + void addStatesToEnter(const Arabica::DOM::Node<std::string>& state, + Arabica::XPath::NodeSet<std::string>& statesToEnter, + Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry); + + void exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); + void exitInterpreter(); + + Arabica::XPath::NodeSet<std::string> selectEventlessTransitions(); + Arabica::XPath::NodeSet<std::string> selectTransitions(const std::string& event); + Arabica::XPath::NodeSet<std::string> filterPreempted(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); + bool isPreemptingTransition(const Arabica::DOM::Node<std::string>& t1, const Arabica::DOM::Node<std::string>& t2); + +}; + +} + +#endif /* end of include guard: INTERPRETERDRAFT6_H_JAXK9FE1 */ diff --git a/src/uscxml/interpreter/InterpreterDraft7.cpp b/src/uscxml/interpreter/InterpreterDraft7.cpp new file mode 100644 index 0000000..9542146 --- /dev/null +++ b/src/uscxml/interpreter/InterpreterDraft7.cpp @@ -0,0 +1,439 @@ +#include "InterpreterDraft7.h" + +#include <glog/logging.h> + +namespace uscxml { + +using namespace Arabica::XPath; +using namespace Arabica::DOM; + +/** +procedure interpret(doc): + if not valid(doc): failWithError() + expandScxmlSource(doc) + configuration = new OrderedSet() + statesToInvoke = new OrderedSet() + internalQueue = new Queue() + externalQueue = new BlockingQueue() + historyValue = new HashTable() + datamodel = new Datamodel(doc) + if doc.binding == "early": + initializeDatamodel(datamodel, doc) + running = true + executeGlobalScriptElement(doc) + enterStates([doc.initial.transition]) + mainEventLoop() + */ +void InterpreterDraft7::interpret() { + if (!_isInitialized) + init(); + + if (!_scxml) + return; + + _sessionId = getUUID(); + + std::string datamodelName; + if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "datamodel")) + datamodelName = ATTR(_scxml, "datamodel"); + if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "profile")) // SCION SCXML uses profile to specify datamodel + datamodelName = ATTR(_scxml, "profile"); + if(datamodelName.length() > 0) + _dataModel = Factory::createDataModel(datamodelName, this); + if(datamodelName.length() > 0 && !_dataModel) { + LOG(ERROR) << "No datamodel for " << datamodelName << " registered"; + } + + if (_dataModel) { + _dataModel.assign("_x.args", _cmdLineOptions); + if (_httpServlet) { + Data data; + data.compound["location"] = Data(_httpServlet->getURL(), Data::VERBATIM); + _dataModel.assign("_ioprocessors['http']", data); + } + } + + setupIOProcessors(); + + _running = true; + _binding = (HAS_ATTR(_scxml, "binding") && boost::iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); + + // @TODO: Reread http://www.w3.org/TR/scxml/#DataBinding + + if (_dataModel && _binding == EARLY) { + // initialize all data elements + NodeSet<std::string> dataElems = _xpath.evaluate("//" + _xpathPrefix + "data", _document).asNodeSet(); + for (unsigned int i = 0; i < dataElems.size(); i++) { + initializeData(dataElems[i]); + } + } else if(_dataModel) { + // initialize current data elements + NodeSet<std::string> topDataElems = filterChildElements(_xmlNSPrefix + "data", filterChildElements(_xmlNSPrefix + "datamodel", _scxml)); + for (unsigned int i = 0; i < topDataElems.size(); i++) { + initializeData(topDataElems[i]); + } + } + + // executeGlobalScriptElements + NodeSet<std::string> globalScriptElems = _xpath.evaluate("/" + _xpathPrefix + "scxml/" + _xpathPrefix + "script", _document).asNodeSet(); + for (unsigned int i = 0; i < globalScriptElems.size(); i++) { + if (_dataModel) + executeContent(globalScriptElems[i]); + } + + // initial transition might be implict + NodeSet<std::string> initialTransitions = _xpath.evaluate("/" + _xpathPrefix + "scxml/" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", _document).asNodeSet(); + if (initialTransitions.size() == 0) { + Arabica::XPath::NodeSet<std::string> initialStates = getInitialStates(); + + for (int i = 0; i < initialStates.size(); i++) { + Arabica::DOM::Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial"); + initialElem.setAttribute("generated", "true"); + Arabica::DOM::Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition"); + transitionElem.setAttribute("target", ATTR(initialStates[i], "id")); + initialElem.appendChild(transitionElem); + _scxml.appendChild(initialElem); + initialTransitions.push_back(transitionElem); + } + } + enterStates(initialTransitions); + + // assert(hasLegalConfiguration()); + mainEventLoop(); + + if (_parentQueue) { + // send one final event to unblock eventual listeners + Event quit; + quit.name = "done.state.scxml"; + _parentQueue->push(quit); + } + + // set datamodel to null from this thread + if(_dataModel) + _dataModel = DataModel(); + +} + +/** + * Called with a single data element from the topmost datamodel element. + */ +void InterpreterDraft7::initializeData(const Arabica::DOM::Node<std::string>& data) { + if (!_dataModel) { + LOG(ERROR) << "Cannot initialize data when no datamodel is given!"; + return; + } + try { + if (!HAS_ATTR(data, "id")) { + LOG(ERROR) << "Data element has no id!"; + return; + } + + if (HAS_ATTR(data, "expr")) { + std::string value = ATTR(data, "expr"); + _dataModel.assign(ATTR(data, "id"), value); + } else if (HAS_ATTR(data, "src")) { + URL srcURL(ATTR(data, "src")); + if (!srcURL.isAbsolute()) + toAbsoluteURI(srcURL); + + std::stringstream ss; + if (_cachedURLs.find(srcURL.asString()) != _cachedURLs.end()) { + ss << _cachedURLs[srcURL.asString()]; + } else { + ss << srcURL; + _cachedURLs[srcURL.asString()] = srcURL; + } + _dataModel.assign(ATTR(data, "id"), ss.str()); + + } else if (data.hasChildNodes()) { + // search for the text node with the actual script + NodeList<std::string> dataChilds = data.getChildNodes(); + for (int i = 0; i < dataChilds.getLength(); i++) { + if (dataChilds.item(i).getNodeType() == Node_base::TEXT_NODE) { + Data value = Data(dataChilds.item(i).getNodeValue()); + _dataModel.assign(ATTR(data, "id"), value); + break; + } + } + } + + } catch (Event e) { + LOG(ERROR) << "Syntax error in data element:" << std::endl << e << std::endl; + } +} + +/** +procedure mainEventLoop(): + while running: + enabledTransitions = null + macrostepDone = false + # Here we handle eventless transitions and transitions + # triggered by internal events until macrostep is complete + while running and not macrostepDone: + enabledTransitions = selectEventlessTransitions() + if enabledTransitions.isEmpty(): + if internalQueue.isEmpty(): + macrostepDone = true + else: + internalEvent = internalQueue.dequeue() + datamodel["_event"] = internalEvent + enabledTransitions = selectTransitions(internalEvent) + if not enabledTransitions.isEmpty(): + microstep(enabledTransitions.toList()) + # either we're in a final state, and we break out of the loop + if not running: + break; + # or we've completed a macrostep, so we start a new macrostep by waiting for an external event + # Here we invoke whatever needs to be invoked. The implementation of 'invoke' is platform-specific + for state in statesToInvoke: + for inv in state.invoke: + invoke(inv) + statesToInvoke.clear() + # Invoking may have raised internal error events and we iterate to handle them + if not internalQueue.isEmpty(): + continue + # A blocking wait for an external event. Alternatively, if we have been invoked + # our parent session also might cancel us. The mechanism for this is platform specific, + # but here we assume it’s a special event we receive + externalEvent = externalQueue.dequeue() + if isCancelEvent(externalEvent): + running = false + continue + datamodel["_event"] = externalEvent + for state in configuration: + for inv in state.invoke: + if inv.invokeid == externalEvent.invokeid: + applyFinalize(inv, externalEvent) + if inv.autoforward: + send(inv.id, externalEvent) + enabledTransitions = selectTransitions(externalEvent) + if not enabledTransitions.isEmpty(): + microstep(enabledTransitions.toList()) + # End of outer while running loop. If we get here, we have reached a top-level final state or have been cancelled + exitInterpreter() + */ +void InterpreterDraft7::mainEventLoop() { +} + +/** +procedure exitInterpreter(): + statesToExit = configuration.toList().sort(exitOrder) + for s in statesToExit: + for content in s.onexit: + executeContent(content) + for inv in s.invoke: + cancelInvoke(inv) + configuration.delete(s) + if isFinalState(s) and isScxmlState(s.parent): + returnDoneEvent(s.donedata) + */ +void InterpreterDraft7::exitInterpreter() { +} + +/** +procedure microstep(enabledTransitions): + exitStates(enabledTransitions) + executeTransitionContent(enabledTransitions) + enterStates(enabledTransitions) + */ +void InterpreterDraft7::microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { +} + +/** +function selectEventlessTransitions(): + enabledTransitions = new OrderedSet() + atomicStates = configuration.toList().filter(isAtomicState).sort(documentOrder) + for state in atomicStates: + loop: for s in [state].append(getProperAncestors(state, null)): + for t in s.transition: + if not t.event and conditionMatch(t): + enabledTransitions.add(t) + break loop + enabledTransitions = filterPreempted(enabledTransitions) + return enabledTransitions + */ +Arabica::XPath::NodeSet<std::string> InterpreterDraft7::selectEventlessTransitions() { +} + +/** +function selectTransitions(event): + enabledTransitions = new OrderedSet() + atomicStates = configuration.toList().filter(isAtomicState).sort(documentOrder) + for state in atomicStates: + loop: for s in [state].append(getProperAncestors(state, null)): + for t in s.transition: + if t.event and nameMatch(t.event, event.name) and conditionMatch(t): + enabledTransitions.add(t) + break loop + enabledTransitions = removeConflictingTransitions(enabledTransitions) + return enabledTransitions + */ +Arabica::XPath::NodeSet<std::string> InterpreterDraft7::selectTransitions(const std::string& event) { +} + +/** +procedure enterStates(enabledTransitions): + statesToEnter = new OrderedSet() + statesForDefaultEntry = new OrderedSet() + computeEntrySet(enabledTransitions, statesToEnter, statesForDefaultEntry) + for s in statesToEnter.toList().sort(entryOrder): + configuration.add(s) + statesToInvoke.add(s) + if binding == "late" and s.isFirstEntry: + initializeDataModel(datamodel.s,doc.s) + s.isFirstEntry = false + for content in s.onentry: + executeContent(content) + if statesForDefaultEntry.isMember(s): + executeContent(s.initial.transition) + if isFinalState(s): + if isSCXMLElement(s.parent): + running = false + else: + parent = s.parent + grandparent = parent.parent + internalQueue.enqueue(new Event("done.state." + parent.id, s.donedata)) + if isParallelState(grandparent): + if getChildStates(grandparent).every(isInFinalState): + internalQueue.enqueue(new Event("done.state." + grandparent.id)) + */ +void InterpreterDraft7::enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { +} + +/** +procedure exitStates(enabledTransitions): + statesToExit = computeExitSet(enabledTransitions) + for s in statesToExit: + statesToInvoke.delete(s) + statesToExit = statesToExit.toList().sort(exitOrder) + for s in statesToExit: + for h in s.history: + if h.type == "deep": + f = lambda s0: isAtomicState(s0) and isDescendant(s0,s) + else: + f = lambda s0: s0.parent == s + historyValue[h.id] = configuration.toList().filter(f) + for s in statesToExit: + for content in s.onexit: + executeContent(content) + for inv in s.invoke: + cancelInvoke(inv) + configuration.delete(s) + */ +void InterpreterDraft7::exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { +} + +/** +function computeExitSet(transitions) + statesToExit = new OrderedSet + for t in transitions: + domain = getTransitionDomain(t) + for s in configuration: + if isDescendant(s,domain): + statesToExit.add(s) + return statesToExit + */ +Arabica::XPath::NodeSet<std::string> InterpreterDraft7::computeExitSet(const Arabica::XPath::NodeSet<std::string>& enabledTransitions, + const Arabica::XPath::NodeSet<std::string>& statesToExit) { +} + +/** + procedure computeEntrySet(transitions, statesToEnter, statesForDefaultEntry) + for t in transitions: + statesToEnter.union(getTargetStates(t.target)) + for s in statesToEnter: + addDescendentStatesToEnter(s,statesToEnter,statesForDefaultEntry) + for t in transitions: + ancestor = getTransitionDomain(t) + for s in getTargetStates(t.target)): + addAncestorStatesToEnter(s, ancestor, statesToEnter, statesForDefaultEntry) + */ +Arabica::XPath::NodeSet<std::string> InterpreterDraft7::computeEntrySet(const Arabica::XPath::NodeSet<std::string>& transitions, + const Arabica::XPath::NodeSet<std::string>& statesToEnter, + const Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) { +} + +/** +function removeConflictingTransitions(enabledTransitions): + filteredTransitions = new OrderedSet() + // toList sorts the transitions in the order of the states that selected them + for t1 in enabledTransitions.toList(): + t1Preempted = false; + transitionsToRemove = new OrderedSet() + for t2 in filteredTransitions.toList(): + if computeExitSet(t1).hasIntersection(computeExitSet(t2)): + if isDescendent(t1.source, t2.source): + transitionsToRemove.add(t2) + else: + t1Preempted = true + break + if not t1Preempted: + for t3 in transitionsToRemove.toList(): + filteredTransitions.delete(t3) + filteredTransitions.add(t1) + + return filteredTransitions + */ +Arabica::XPath::NodeSet<std::string> InterpreterDraft7::removeConflictingTransitions(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { +} + +/** + function getTransitionDomain(t) + tstates = getTargetStates(t.target) + if not tstates + return t.source + elif t.type == "internal" and isCompoundState(t.source) and tstates.every(lambda s: isDescendant(s,t.source)): + return t.source + else: + return findLCCA([t.source].append(tstates)) + */ +Arabica::DOM::Node<std::string> InterpreterDraft7::getTransitionDomain(const Arabica::DOM::Node<std::string>& transition) { +} + +/** + procedure addDescendentStatesToEnter(state,statesToEnter,statesForDefaultEntry): + if isHistoryState(state): + if historyValue[state.id]: + for s in historyValue[state.id]: + addDescendentStatesToEnter(s,statesToEnter,statesForDefaultEntry) + addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry) + else: + for t in state.transition: + for s in getTargetStates(t.target): + addDescendentStatesToEnter(s,statesToEnter,statesForDefaultEntry) + addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry) + else: + statesToEnter.add(state) + if isCompoundState(state): + statesForDefaultEntry.add(state) + for s in getTargetStates(state.initial): + addDescendentStatesToEnter(s,statesToEnter,statesForDefaultEntry) + addAncestorStatesToEnter(s, state, statesToEnter, statesForDefaultEntry) + else: + if isParallelState(state): + for child in getChildStates(state): + if not statesToEnter.some(lambda s: isDescendant(s,child)): + addDescendentStatesToEnter(child,statesToEnter,statesForDefaultEntry) + */ +Arabica::XPath::NodeSet<std::string> InterpreterDraft7::addDescendentStatesToEnter(const Arabica::DOM::Node<std::string>& state, + const Arabica::XPath::NodeSet<std::string>& statesToEnter, + const Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) { +} + +/** + procedure addAncestorsToEnter(state, ancestor, statesToEnter, statesForDefaultEntry) + for anc in getProperAncestors(state,ancestor): + statesToEnter.add(anc) + if isParallelState(anc): + for child in getChildStates(anc): + if not statesToEnter.some(lambda s: isDescendant(s,child)): + addStatesToEnter(child,statesToEnter,statesForDefaultEntry) + */ +Arabica::XPath::NodeSet<std::string> InterpreterDraft7::addAncestorsStatesToEnter(const Arabica::DOM::Node<std::string>& state, + const Arabica::DOM::Node<std::string>& ancestor, + const Arabica::XPath::NodeSet<std::string>& statesToEnter, + const Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry) { +} + + +}
\ No newline at end of file diff --git a/src/uscxml/interpreter/InterpreterDraft7.h b/src/uscxml/interpreter/InterpreterDraft7.h new file mode 100644 index 0000000..e784e84 --- /dev/null +++ b/src/uscxml/interpreter/InterpreterDraft7.h @@ -0,0 +1,46 @@ +#ifndef INTERPRETERDRAFT7_H_WLJEI019 +#define INTERPRETERDRAFT7_H_WLJEI019 + +#include "uscxml/Interpreter.h" + +namespace uscxml { + +class InterpreterDraft7 : public Interpreter { + void interpret(); + void mainEventLoop(); + void exitInterpreter(); + + void microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); + + Arabica::XPath::NodeSet<std::string> selectEventlessTransitions(); + Arabica::XPath::NodeSet<std::string> selectTransitions(const std::string& event); + + void enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); + void exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); + + Arabica::XPath::NodeSet<std::string> computeExitSet(const Arabica::XPath::NodeSet<std::string>& enabledTransitions, + const Arabica::XPath::NodeSet<std::string>& statesToExit); + + Arabica::XPath::NodeSet<std::string> computeEntrySet(const Arabica::XPath::NodeSet<std::string>& transitions, + const Arabica::XPath::NodeSet<std::string>& statesToEnter, + const Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry); + + Arabica::XPath::NodeSet<std::string> removeConflictingTransitions(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); + Arabica::DOM::Node<std::string> getTransitionDomain(const Arabica::DOM::Node<std::string>& transition); + + Arabica::XPath::NodeSet<std::string> addDescendentStatesToEnter(const Arabica::DOM::Node<std::string>& state, + const Arabica::XPath::NodeSet<std::string>& statesToEnter, + const Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry); + + Arabica::XPath::NodeSet<std::string> addAncestorsStatesToEnter(const Arabica::DOM::Node<std::string>& state, + const Arabica::DOM::Node<std::string>& ancestor, + const Arabica::XPath::NodeSet<std::string>& statesToEnter, + const Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry); + + void initializeData(const Arabica::DOM::Node<std::string>& data); + +}; + +} + +#endif /* end of include guard: INTERPRETERDRAFT7_H_WLJEI019 */ diff --git a/test/run-scxml-test-framework.sh b/test/run-scxml-test-framework.sh index 83cb403..804eb9f 100755 --- a/test/run-scxml-test-framework.sh +++ b/test/run-scxml-test-framework.sh @@ -157,7 +157,8 @@ TESTS="" # TESTS="${TESTS} scxml-test-framework/test/targetless-transition/test2.scxml" # passed # TESTS="${TESTS} scxml-test-framework/test/targetless-transition/test3.scxml" # failed -TESTS="${TESTS} scxml-test-framework/test/*/*.scxml" +# TESTS="${TESTS} scxml-test-framework/test/*/*.scxml" +TESTS="${TESTS} scxml-test-framework/test/w3c/*.scxml" #trap 'killall ${SCXML_TEST_FRAMEWORK_NAME}' 0 #$SCXML_TEST_FRAMEWORK_FULL & diff --git a/test/samples/w3c/Blackjack.scxml b/test/samples/w3c/Blackjack.scxml deleted file mode 100644 index 4f55e53..0000000 --- a/test/samples/w3c/Blackjack.scxml +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0"?> -<?access-control allow="*"?> -<scxml version="1.0" datamodel="ecmascript" initial="master"> <state id="master"> - <initial id="init1"> - <transition target="_home"/> - </initial> - <transition event="new_dealer" target="NewDealer"/> - <transition event="mumble" target="_home"/> <!-- bail out to caller --> - <transition event="silence" target="_home"/> <!-- bail out to caller --> - <state id="_home"> - <onenter> - <script> - _data = {}; - </script> - </onenter> - <invoke src="datamodel.v3#InitDataModel" type="vxml3"> - <finalize> - <script> - var n; - for (n in event) { - _data[n] = event[n]; - } - </script> - </finalize> - </invoke> - <transition event="success" target="Welcome"/> - </state> - - <state id="Welcome"> - <invoke src="dialog.vxml#Welcome" type="vxml3"> - <param name="skinpath" expr="skinpath"/> - </invoke> - <transition event="success" target="Intro2"/> - </state> - - <state id="Intro2"> - <invoke src="dialog.vxml#Intro2" type="vxml3"> - <param name="skinpath" expr="skinpath"/> - </invoke> - <transition event="success" target="EvalDeal"/> - </state> - - <state id="EvalDeal"> - <onenter> - <script>enterEvalDeal();</script> - </onenter> - <invoke src="dialog.vxml#EvalDeal" type="vxml3"> - <param name="skinpath" expr="skinpath"/> - <param name="playercard1" expr="playercard1"/> - <param name="playercard2" expr="playercard2"/> - <param name="playertotal" expr="blackjack.GetTotalOf('caller').toString()"/> - <param name="dealercardshowing" expr="dealercardshowing"/> - </invoke> - <transition event="success" target="AskHit"/> - </state> - - <state id="AskHit"> - <invoke src="dialog.vxml#AskHit" type="vxml3"> - <param name="skinpath" expr="skinpath"/> - <finalize> - <script>finalizeAskHit();</script> - </finalize> - </invoke> - <transition event="hit" target="PlayNewCard"/> - <transition event="stand" target="PlayDone"/> - </state> - - <state id="PlayNewCard"> - <invoke src="dialog.vxml#PlayNewCard" type="vxml3"> - <param name="skinpath" expr="skinpath"/> - <param name="playernewcard" expr="playernewcard"/> - <param name="playertotal" expr="blackjack.GetTotalOf('caller').toString()"/> - </invoke> - <transition event="success" cond="blackjack.GetTotalOf('caller') >= 21" target="PlayDone"/> - <transition event="success" target="AskHit"/> <!-- less than 21 --> - </state> - - <state id="PlayDone"> - <onenter> - <script>enterPlayDone();</script> - </onenter> - <invoke src="dialog.vxml#PlayDone" type="vxml3"> - <param name="skinpath" expr="skinpath"/> - <param name="gameresult" expr="blackjack.GetGameResult()"/> - <param name="dealertotal" expr="blackjack.GetTotalOf('dealer').toString()"/> - </invoke> - <transition event="playagain" target="Intro2"/> - <transition event="quit" target="_home"/> - </state> - - <state id="NewDealer"> - <onenter> - <script>enterNewDealer();</script> - </onenter> - <invoke src="dialog.vxml#Dummy" type="vxml3"/> - <transition event="success" target="Welcome"/> - </state> - </state> -</scxml> diff --git a/test/samples/w3c/Main.scxml b/test/samples/w3c/Main.scxml deleted file mode 100644 index 4c03631..0000000 --- a/test/samples/w3c/Main.scxml +++ /dev/null @@ -1,204 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- A wrapper state that contains all other states in this file -- it represents the complete state machine --> -<scxml - xmlns:xi="http://www.w3.org/2001/XInclude" - version="1.0" - initial="Main" - datamodel="ecmascript"> - <state id="Main"> - <!-- its initial state is Test1 --> - <initial> - <transition target="Test1"/> - </initial> - - <!-- Really simple state showing the basic syntax. --> - <state id="Test1"> - <initial> - <transition target="Test1Sub1"/> - </initial> - <!-- Runs before we go into the substate --> - <onentry> - <log expr="'Inside Test1'"/> - </onentry> - - <!-- Here is our first substate --> - <state id="Test1Sub1"> - <onentry> - <log expr="'Inside Test1Sub1.'"/> - </onentry> - <onexit> - <log expr="'Leaving Test1Sub1'"/> - </onexit> - <!-- Go to Sub2 on Event1 --> - <transition event="Event1" target="Test1Sub2"/> - </state> - - <!-- Here is the second substate - It is final, so Test1 is done when we get here --> - <final id="Test1Sub2"/> - - <!-- We get this event when we reach Test1Sub2. --> - <transition event="Test1.done" target="Test2"/> - - <!-- We run this on the way out of Test1 --> - <onexit> - <log expr="'Leaving Test1...'"/> - </onexit> - </state> - - <state id="Test2"> - <initial> - <transition target="Test2Sub1"/> - </initial> - - <!-- This time we reference a state - defined in an external file. --> - <xi:include href="Test2Sub1.xml" parse="text"/> - - <final id="Test2Sub2"/> - - <!-- Test2Sub2 is defined as final, so this - event is generated when we reach it --> - <transition event="done.state.Test2" next="Test3"/> - </state> - - <state id="Test3"> - <initial> - <transition target="Test3Sub1"/> - </initial> - - <state id="Test3Sub1"> - <onentry> - <log expr="'Inside Test3Sub1...'"/> - <!-- Send our self an event in 5s --> - <send event="'Timer'" delay="'5s'"/> - </onentry> - <!-- Transition on to Test4. - This will exit both us and our parent. --> - <transition event="Timer" target="Test4"/> - <onexit> - <log expr="'Leaving Test3Sub1...'"/> - </onexit> - </state> - - <onexit> - <log expr="'Leaving Test3...'"/> - </onexit> - </state> - - <state id="Test4"> - <onentry> - <log expr="'Inside Test4...'"/> - </onentry> - <initial> - <transition target="Test4Sub1"/> - </initial> - - <state id="Test4Sub1"> - <onexit> - <log expr="'Leaving Test4Sub1...'"/> - </onexit> - <!-- This transition causes the state to exit immediately - after entering Test4Sub1. The transition has no event - or guard so it is always active --> - <transition target="Test5"/> - </state> - </state> - - <state id="Test5"> - <onentry> - <log expr="'Inside Test5...'"/> - </onentry> - <initial> - <transition target="Test5P"/> - </initial> - - <!-- Fire off parallel states. In a more realistic example - the parallel substates Test5PSub1 and Test5PSub2 would themselves - have substates and would do some real work before transitioning to final substates --> - <parallel id="Test5P"> - <state id="Test5PSub1" initial="Test5PSub1Final"> - <final id="Test5PSub1Final"/> - </state> - <state id="Test5PSub2" initial="Test5PSub2Final"> - <final id="Test5PSub2Final"/> - </state> - <onexit> - <log expr="'all parallel states done'"/> - </onexit> - </parallel> - - <!-- The parallel states immediately transition to final substates, - so this event is generated immediately. --> - <transition event="done.state.Test5P" target="Test6"/> - </state> - - <!-- - - This state shows invocation of an external component. - - We will use CCXML + VoiceXML actions as an example - - as it is a good smoke test to show how it all - - fits together. - - Note: In a real app you would likely - - split this over several states but we - - are trying to keep it simple here. - --> - <state id="Test6" - xmlns:ccxml="http://www.w3.org/2002/09/ccxml" - xmlns:v3="http://www.w3.org/2005/07/vxml3"> - <datamodel> - <data name="ccxmlid" expr="32459"/> - <date name="v3id" expr="17620"/> - <data name="dest" expr="'tel:+18315552020'"/> - <data name="src" expr="'helloworld2.vxml'"/> - <data name="id" expr="'HelloWorld'"/> - </datamodel> - - <onentry> - <!-- Use <send> a message to a CCXML Processor asking it to run createcall --> - <send target="ccxmlid" type="basichttp" event="ccxml:createcall" namelist="dest"/> - </onentry> - - <transition event="ccxml:connection.connected"> - <!-- Here as a platform-specific extension we use example V3 - Custom Action Elements instead of send. The implementation of this logic - would be platform-dependent. --> - <v3:form id="HelloWorld"> - <v3:block><v3:prompt>Hello World!</v3:prompt></v3:block> - </v3:form> - </transition> - - <transition event="v3:HelloWorld.done"> - <!-- Here we are using the low level <send> - element to run a v3 form. Note that the event "v3:HelloWorld.done" - is assumed either to be set/sent explicitly by the v3:form code or - implicitly by some process outside of the v3:form --> - <send target="v3id" type="basichttp" event="v3:formstart" namelist="src id"/> - </transition> - - <transition event="v3:HelloWorld2.done"> - <!-- we use _event.data to access data in the event we're processing. - Again we assume the v3:HelloWorld2.done is set/sent from outside - this document --> - <ccxml:disconnect connectionid="_event.data.connectionid"/> - </transition> - - <transition event="ccxml:connection.disconnected" target="Done"/> - - <transition event="send.failed" target="Done"> - <!-- If we get an error event we move to the Done state that - is a final state. --> - <log expr="'Sending to and External component failed'"/> - </transition> - - <onexit> - <log expr="'Finished with external component'"/> - </onexit> - </state> - - <!-- This final state is an immediate child of Main - - when we get here, Main.done is generated. --> - <final id="Done"/> - <!-- End of Main > --> - </state> -</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/Test2Sub1.xml b/test/samples/w3c/Test2Sub1.xml deleted file mode 100644 index 6ab7b98..0000000 --- a/test/samples/w3c/Test2Sub1.xml +++ /dev/null @@ -1,9 +0,0 @@ -<!-- This is an example substate defined in -- an external file and included by Main.scxml. ---> -<state id="Test2Sub1"> -<onentry> - <log expr="'Inside Test2Sub1'"/> -</onentry> -<transition event="Event2" target="Test2Sub2"/> -</state> diff --git a/test/samples/w3c/TrafficReport.scxml b/test/samples/w3c/TrafficReport.scxml deleted file mode 100644 index 09e2e93..0000000 --- a/test/samples/w3c/TrafficReport.scxml +++ /dev/null @@ -1,88 +0,0 @@ -<?xml version="1.0"?> -<?access-control allow="*"?> -<!-- A comment! --> -<scxml version="1.0" initial="Intro" datamodel="ecmascript"> - <state id="Intro"> - <invoke src="dialog.vxml#Intro" type="vxml2"/> - <transition event="success" cond="sessionChrome.playAds" target="PlayAds"/> - <transition event="success" cond="!sessionChrome.playAds && ANIQuality" - target="ShouldGoBack"/> - <transition event="success" cond="!sessionChrome.playAds && !ANIQuality" - target="StartOver"/> - </state> - - <state id="PlayAds"> - <invoke src="dialog.vxml#PlayAds" type="vxml2"/> - <transition event="success" cond="ANIQuality" target="ShouldGoBack"/> - <transition event="success" cond="!ANIQuality" target="StartOver"/> - </state> - - <state id="StartOver"> - <onentry> - <script>enterStartOver();</script> - </onentry> - <invoke src="dialog.vxml#StartOver" type="vxml2"> - <param name="gotItFromANI" expr="gotItFromANI"/> - <finalize> - <script>finalizeStartOver();</script> - </finalize> - </invoke> - <transition event="success" target="ShouldGoBack"/> - <transition event="doOver" target="StartOver"/> - <transition event="restart" target="Intro"/> <!-- bail out to caller --> - </state> - - <state id="ShouldGoBack"> - <invoke src="dialog.vxml#ShouldGoBack" type="vxml2"> - <param name="cityState" expr="cityState"/> - <param name="gotItFromANI" expr="gotItFromANI"/> - <finalize> - <script>finalizeShouldGoBack();</script> - </finalize> - </invoke> - <transition event="highWay" target="HighwayReport"/> - <transition event="go_back" target="StartOver"/> - <transition event="doOver" target="ShouldGoBack"/> - <transition event="restart" target="Intro"/> - </state> - - <state id="HighwayReport"> - <invoke src="dialog.vxml#HighwayReport" type="vxml2"> - <param name="cityState" expr="cityState"/> - <param name="gotItFromANI" expr="gotItFromANI"/> - <param name="playHRPrompt" expr="playHRPrompt"/> - <param name="metroArea" expr="metroArea"/> - <finalize> - <script>finalizeHighwayReport();</script> - </finalize> - </invoke> - <transition event="highway" target="PlayHighway"/> - <transition event="go_back" target="StartOver"/> - <transition event="doOver" target="HighwayReport"/> - <transition event="fullreport" target="FullReport"/> - <transition event="restart" target="Intro"/> - </state> - - <state id="FullReport"> - <invoke src="dialog.vxml#FullReport" type="vxml2"> - <param name="cityState" expr="cityState"/> - <param name="metroArea" expr="metroArea"/> - <finalize> - <script>finalizeFullReport();</script> - </finalize> - </invoke> - <transition event="go_back" target="HighwayReport"/> - <transition event="new_city" target="StartOver"/> - </state> - - <state id="PlayHighway"> - <invoke src="dialog.vxml#PlayHighway" type="vxml2"> - <param name="cityState" expr="cityState"/> - <param name="curHighway" expr="curHighway"/> - <finalize> - <script>finalizePlayHighway();</script> - </finalize> - </invoke> - <transition event="go_back" target="HighwayReport"/> - </state> -</scxml> diff --git a/test/samples/w3c/calc.scxml b/test/samples/w3c/calc.scxml deleted file mode 100644 index e759b45..0000000 --- a/test/samples/w3c/calc.scxml +++ /dev/null @@ -1,158 +0,0 @@ -<?xml version="1.0" ?> -<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" - initial="on" datamodel="ecmascript" name="calc"> - <datamodel> - <data id="long_expr" /> - <data id="short_expr" expr="0" /> - <data id="res" /> - </datamodel> - <state id="wrapper" initial="on"> - <state id="on" initial="ready"> - <onentry> - <send event="DISPLAY.UPDATE" /> - </onentry> - <state id="ready" initial="begin"> - <state id="begin"> - <transition event="OPER.MINUS" target="negated1" /> - <onentry> - <send event="DISPLAY.UPDATE" /> - </onentry> - </state> - <state id="result"> - </state> - <transition event="OPER" target="opEntered" /> - <transition event="DIGIT.0" target="zero1"> - <assign location="short_expr" expr="''" /> - </transition> - <transition event="DIGIT" target="int1"> - <assign location="short_expr" expr="''" /> - </transition> - <transition event="POINT" target="frac1"> - <assign location="short_expr" expr="''" /> - </transition> - </state> - <state id="negated1"> - <onentry> - <assign location="short_expr" expr="'-'" /> - <send event="DISPLAY.UPDATE" /> - </onentry> - <transition event="DIGIT.0" target="zero1" /> - <transition event="DIGIT" target="int1" /> - <transition event="POINT" target="frac1" /> - </state> - <state id="operand1"> - <state id="zero1"> - <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int1" /> - <transition event="POINT" target="frac1" /> - </state> - <state id="int1"> - <transition event="POINT" target="frac1" /> - <transition event="DIGIT"> - <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> - <send event="DISPLAY.UPDATE" /> - </transition> - <onentry> - <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> - <send event="DISPLAY.UPDATE" /> - </onentry> - </state> - <state id="frac1"> - <onentry> - <assign location="short_expr" expr="short_expr+'.'" /> - <send event="DISPLAY.UPDATE" /> - </onentry> - <transition event="DIGIT"> - <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> - <send event="DISPLAY.UPDATE" /> - </transition> - </state> - <transition event="OPER" target="opEntered" /> - </state> - <state id="opEntered"> - <transition event="OPER.MINUS" target="negated2" /> - <transition event="POINT" target="frac2" /> - <transition event="DIGIT.0" target="zero2" /> - <transition event="DIGIT" target="int2" /> - <onentry> - <raise event="CALC.SUB" /> - <send target="_internal" event="OP.INSERT"> - <param name="operator" expr="_event.name" /> - </send> - </onentry> - </state> - <state id="negated2"> - <onentry> - <assign location="short_expr" expr="'-'" /> - <send event="DISPLAY.UPDATE" /> - </onentry> - <transition event="DIGIT.0" target="zero2" /> - <transition event="DIGIT" target="int2" /> - <transition event="POINT" target="frac2" /> - </state> - <state id="operand2"> - <state id="zero2"> - <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int2" /> - <transition event="POINT" target="frac2" /> - </state> - <state id="int2"> - <transition event="DIGIT"> - <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> - <send event="DISPLAY.UPDATE" /> - </transition> - <onentry> - <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> - <send event="DISPLAY.UPDATE" /> - </onentry> - <transition event="POINT" target="frac2" /> - </state> - <state id="frac2"> - <onentry> - <assign location="short_expr" expr="short_expr +'.'" /> - <send event="DISPLAY.UPDATE" /> - </onentry> - <transition event="DIGIT"> - <assign location="short_expr" expr="short_expr +_event.name.substr(_event.name.lastIndexOf('.')+1)" /> - <send event="DISPLAY.UPDATE" /> - </transition> - </state> - <transition event="OPER" target="opEntered"> - <raise event="CALC.SUB" /> - <raise event="OP.INSERT" /> - </transition> - <transition event="EQUALS" target="result"> - <raise event="CALC.SUB" /> - <raise event="CALC.DO" /> - </transition> - </state> - <transition event="C" target="on" /> - </state> - <transition event="CALC.DO"> - <assign location="short_expr" expr="''+ res" /> - <assign location="long_expr" expr="''" /> - <assign location="res" expr="0" /> - </transition> - <transition event="CALC.SUB"> - <if cond="short_expr!=''"> - <assign location="long_expr" expr="long_expr+'('+short_expr+')'" /> - </if> - <assign location="res" expr="eval(long_expr)" /> - <assign location="short_expr" expr="''" /> - <send event="DISPLAY.UPDATE" /> - </transition> - <transition event="DISPLAY.UPDATE"> - <log level="0" label="'result'" expr=".short_expr==''?res:short_expr" /> - </transition> - <transition event="OP.INSERT"> - <log level="0" expr="_event.data[0]" /> - <if cond="_event.data[0] == 'OPER.PLUS'"> - <assign location="long_expr" expr="long_expr+'+'" /> - <elseif cond="_event.data[0]=='OPER.MINUS'" /> - <assign location="long_expr" expr="long_expr+'-'" /> - <elseif cond="_event.data[0]=='OPER.STAR'" /> - <assign location="long_expr" expr="long_expr+'*'" /> - <elseif cond="_event.data[0]=='OPER.DIV'" /> - <assign location="long_expr" expr="long_expr+'/'" /> - </if> - </transition> - </state> -</scxml> diff --git a/test/samples/w3c/confEcma.xsl b/test/samples/w3c/confEcma.xsl new file mode 100644 index 0000000..0ec3d3d --- /dev/null +++ b/test/samples/w3c/confEcma.xsl @@ -0,0 +1,720 @@ +<?xml version="1.0"?> +<!-- Copyright 1998-2003 W3C (MIT, ERCIM, Keio), All Rights Reserved. See http://www.w3.org/Consortium/Legal/. --> +<xsl:stylesheet + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:conf="http://www.w3.org/2005/scxml-conformance" + version="2.0"> + + + + +<!-- Copy everything that doesn't match other rules --> +<xsl:template match="/ | @* | node()"> + <xsl:copy> + <xsl:apply-templates select="@* | node()"/> + </xsl:copy> +</xsl:template> + +<!-- Success criteria --> + +<xsl:template match="//@conf:targetpass"> + <xsl:attribute name="target">pass</xsl:attribute> +</xsl:template> + +<xsl:template match="conf:pass"> + <final xmlns="http://www.w3.org/2005/07/scxml" id="pass"> + <onentry> + <log label="Outcome" expr="'pass'"/> + </onentry> + </final> +</xsl:template> + +<!-- Failure criteria --> + +<xsl:template match="//@conf:targetfail"> + <xsl:attribute name="target">fail</xsl:attribute> +</xsl:template> + +<xsl:template match="conf:fail"> + <final xmlns="http://www.w3.org/2005/07/scxml" id="fail"> + <onentry> + <log label="Outcome" expr="'fail'"/> + </onentry> +</final> +</xsl:template> + +<!-- datamodel --> +<xsl:template match="//@conf:datamodel"> + <xsl:attribute name="datamodel">ecmascript</xsl:attribute> +</xsl:template> + + +<!-- creates id for <data> element, etc. --> +<xsl:template match="//@conf:id"> + <xsl:attribute name="id">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + + +<!-- creates name for <param>, etc. --> +<xsl:template match="//@conf:name"> + <xsl:attribute name="name">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + + +<!-- creates location for <assign>, etc. --> +<xsl:template match="//@conf:location"> + <xsl:attribute name="location">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- uses system var as location for <assign>, etc. --> +<xsl:template match="//@conf:systemVarLocation"> + <xsl:attribute name="location"><xsl:value-of select="." /></xsl:attribute> +</xsl:template> + + + + +<!-- expr is evaluated --> +<xsl:template match="//@conf:expr"> + <xsl:attribute name="expr"><xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- targetexpr is the corresponding ID --> +<xsl:template match="//@conf:targetVar"> + <xsl:attribute name="targetexpr">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- expr is quoted --> +<xsl:template match="//@conf:quoteExpr"> + <xsl:attribute name="expr">'<xsl:value-of select="." />'</xsl:attribute> +</xsl:template> + +<!-- an expr that is the value of a variable --> +<xsl:template match="//@conf:varExpr"> + <xsl:attribute name="expr">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- in EcmaScript, this is the same as varExpr --> +<xsl:template match="//@conf:varChildExpr"> + <xsl:attribute name="expr">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- an expr that is the value of a system variable --> +<xsl:template match="//@conf:systemVarExpr"> + <xsl:attribute name="expr"><xsl:value-of select="." /></xsl:attribute> +</xsl:template> + + +<!-- an expr that is the value of a non-existent substructure of a variable --> +<xsl:template match="//@conf:varNonexistentStruct"> + <xsl:attribute name="expr">Var<xsl:value-of select="." />.bar</xsl:attribute> +</xsl:template> + + +<!-- this should return a value that cannot be assigned to a var. --> +<xsl:template match="//@conf:illegalExpr"> + <xsl:attribute name="expr">return</xsl:attribute> +</xsl:template> + +<!-- this should add 1 to the value of the specified variable --> +<xsl:template match="conf:incrementID"> + <assign xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="location">Var<xsl:value-of select="@id"/></xsl:attribute> + <xsl:attribute name="expr">Var<xsl:value-of select="@id"/> + 1</xsl:attribute> + </assign> + </xsl:template> + +<!-- this should concatenate the value of the id2 to id1 and assign the result to id1 --> +<xsl:template match="conf:concatVars"> + <assign xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="location">Var<xsl:value-of select="@id1"/></xsl:attribute> + <xsl:attribute name="expr">Var<xsl:value-of select="@id1"/> + Var<xsl:value-of select="@id2"/></xsl:attribute> + </assign> + </xsl:template> + +<!-- assigns the sum of the values of two vars to thefirst var--> +<xsl:template match="//conf:sumVars"> + <assign xmlns="http://www.w3.org/2005/07/scxml"> +<xsl:attribute name="location">Var<xsl:value-of select="@id1"/></xsl:attribute> +<xsl:attribute name="expr">Var<xsl:value-of select="@id1"/> + Var<xsl:value-of select="@id2"/></xsl:attribute> + </assign> + </xsl:template> + +<!-- this should return an illegal target for <send> causing a send error to be raised --> +<xsl:template match="//@conf:illegalTarget"> + <xsl:attribute name="target">baz</xsl:attribute> +</xsl:template> + +<!-- this returns an legal, but unreachable, target for <send> causing a send error to be raised --> +<xsl:template match="//@conf:unreachableTarget"> + <xsl:attribute name="target">#_scxml_foo</xsl:attribute> +</xsl:template> + +<!-- this produces illegal content for <send> causing the message to be rejected --> +<xsl:template match="//conf:illegalContent"> + <content xmlns="http://www.w3.org/2005/07/scxml"> xyz </content> +</xsl:template> + +<!-- a content element whose value is the string 'foo' --> +<xsl:template match="//conf:contentFoo"> + <content xmlns="http://www.w3.org/2005/07/scxml">foo</content> +</xsl:template> + +<!-- this returns something that is guaranteed not to be the ID of the current session --> +<xsl:template match="//@conf:invalidSessionID"> + <xsl:attribute name="expr">27</xsl:attribute> +</xsl:template> + +<!-- this returns something that is guaranteed not to be a valid event I/O processor --> +<xsl:template match="//@conf:invalidSendType"> + <xsl:attribute name="type">27</xsl:attribute> +</xsl:template> + +<!-- same value in an expr --> +<xsl:template match="//@conf:invalidSendTypeExpr"> + <xsl:attribute name="expr">27</xsl:attribute> +</xsl:template> + +<!-- exprs that return the value of the event fields --> + +<xsl:template match="//@conf:eventName"> + <xsl:attribute name="expr">_event.name</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:eventType"> + <xsl:attribute name="expr">_event.type</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:eventSendid"> + <xsl:attribute name="expr">_event.sendid</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:eventField"> + <xsl:attribute name="expr">_event.<xsl:value-of select="."/></xsl:attribute> +</xsl:template> + +<!-- returns the raw message structure as a string --> +<xsl:template match="//@conf:eventRaw"> + <xsl:attribute name="expr">_event.raw</xsl:attribute> +</xsl:template> + + +<!-- returns the value of the specified item in _event.data --> +<xsl:template match="//@conf:eventDataFieldValue"> + <xsl:attribute name="expr">_event.data.<xsl:value-of select="."/></xsl:attribute> +</xsl:template> + +<!-- returns the value of a KVP specified by <param> from _event.data --> +<xsl:template match="//@conf:eventDataParamValue"> + <xsl:attribute name="expr">_event.data.<xsl:value-of select="."/></xsl:attribute> +</xsl:template> +<!-- returns the value of a KVP specified by <param> from _event.data --> +<xsl:template match="//@conf:eventDataNamelistValue"> + <xsl:attribute name="expr">_event.data.<xsl:value-of select="."/></xsl:attribute> +</xsl:template> + +<!-- returns the location of the scxml event i/o processor --> +<xsl:template match="//@conf:scxmlEventIOLocation"> + <xsl:attribute name="expr">_ioprocessors['http://www.w3.org/TR/scxml/#SCXMLEventProcessor'].location</xsl:attribute> +</xsl:template> + +<!-- templates for the expr versions of the send attributes --> + +<!-- eventexpr takes the value of the specified variable --> +<xsl:template match="//@conf:eventExpr"> + <xsl:attribute name="eventexpr">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- targetexpr takes the value of the specified variable --> +<xsl:template match="//@conf:targetExpr"> + <xsl:attribute name="targetexpr">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- typeexpr takes the value of the specified variable --> +<xsl:template match="//@conf:typeExpr"> + <xsl:attribute name="typeexpr">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- delayexpr takes the value of the specified variable --> +<xsl:template match="//@conf:delayExpr"> + <xsl:attribute name="delayexpr">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- the specified variable is used as idlocation --> +<xsl:template match="//@conf:idlocation"> + <xsl:attribute name="idlocation">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- the specified variable is used as sendidexpr --> +<xsl:template match="//@conf:sendIDExpr"> + <xsl:attribute name="sendidexpr">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- the specified variable is used as srcexpr --> +<xsl:template match="//@conf:srcExpr"> + <xsl:attribute name="srcexpr">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- the specified variable is used as namelist --> +<xsl:template match="//@conf:namelist"> + <xsl:attribute name="namelist">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + + + +<!-- transition conditions --> +<!-- the value is evaluated --> +<xsl:template match="//@conf:idVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> + <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/> + <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> + <xsl:choose> + <xsl:when test="$op='='">==</xsl:when> + <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise> + </xsl:choose> + <xsl:value-of select="regex-group(3)"/> + </xsl:matching-substring> + + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> +<!-- compare two variables --> +<xsl:template match="//@conf:varIdVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> + <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/> + <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> + <xsl:choose> + <xsl:when test="$op='='">==</xsl:when> + <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise> + </xsl:choose>Var<xsl:value-of select="regex-group(3)"/> + </xsl:matching-substring> + + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + + +<!-- test that given var whose value was passed in via namelist has specific value. The value expr is evaluated --> +<xsl:template match="//@conf:namelistIdVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> + <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/> + <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> + <xsl:choose> + <xsl:when test="$op='='">===</xsl:when> + <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise> + </xsl:choose> + <xsl:value-of select="regex-group(3)"/> + </xsl:matching-substring> + + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- true if the two vars/ids have the same value --> +<xsl:template match="//@conf:VarEqVar"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)(\W+)([0-9]+)"> + <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/>===Var<xsl:value-of select="regex-group(3)"/> + </xsl:matching-substring> + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- true if the two vars/ids have the same value, which is a structure, not atomic --> +<xsl:template match="//@conf:VarEqVarStruct"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)(\W+)([0-9]+)"> + <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/>==Var<xsl:value-of select="regex-group(3)"/> + </xsl:matching-substring> + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- the value is quoted --> +<xsl:template match="//@conf:idQuoteVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> +<xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/><xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> +<xsl:choose> +<xsl:when test="$op='='">==</xsl:when> +<xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise></xsl:choose>'<xsl:value-of select="regex-group(3)"/>'</xsl:matching-substring> +</xsl:analyze-string> +</xsl:attribute> +</xsl:template> + +<!-- test on the value of two vars --> +<xsl:template match="//@conf:compareIDVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)([0-9+])"> + <xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/><xsl:text>/text() </xsl:text> + <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> + <xsl:choose> + <xsl:when test="$op='='">=</xsl:when> + <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise> + </xsl:choose>Var<xsl:value-of select="regex-group(3)"/><xsl:text>/text() </xsl:text> + </xsl:matching-substring> + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + + +<!-- test that the event's name fieldhas the value specified --> +<xsl:template match="//@conf:eventNameVal"> + <xsl:attribute name="cond">_event.name == <xsl:text>'</xsl:text><xsl:value-of select="."/><xsl:text>'</xsl:text> + </xsl:attribute> + +</xsl:template> + +<xsl:template match="//@conf:eventvarVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> + <xsl:matching-substring>_event.data['Var<xsl:value-of select="regex-group(1)"/><xsl:text>']</xsl:text> + <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> + <xsl:choose> + <xsl:when test="$op='='">==</xsl:when> + <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise> + </xsl:choose> + <xsl:value-of select="regex-group(3)"/> + </xsl:matching-substring> + + </xsl:analyze-string> + </xsl:attribute> + +</xsl:template> + + + +<!-- return true if variable matches value of system var (var number is first arg, system var name +is the second argument --> +<xsl:template match="//@conf:idSystemVarVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> +<xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/><xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> +<xsl:choose> +<xsl:when test="$op='='">==</xsl:when> +<xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise></xsl:choose><xsl:value-of select="regex-group(3)"/></xsl:matching-substring> +</xsl:analyze-string> +</xsl:attribute> +</xsl:template> + +<!-- return true if event.data field matches the specified value --> + +<xsl:template match="//@conf:eventdataVal"> + <xsl:attribute name="cond">_event.data === '<xsl:value-of select="."/>'</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:emptyEventData"> + <xsl:attribute name="cond">_event.data == null</xsl:attribute> +</xsl:template> + +<!-- return true if the _name system var has the specified quoted value --> +<xsl:template match="//@conf:nameVarVal"> + <xsl:attribute name="cond">_name === '<xsl:value-of select="."/>'</xsl:attribute> +</xsl:template> + +<!-- return true if first var's value is a prefix of the second var's value. Input has form "n m" where n and m are ints.--> +<xsl:template match="//@conf:varPrefix"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="(\w+)(\W)(\w+)"> + <xsl:matching-substring> + <!-- the underscore.string.startswith function compressed into one line below: + <xsl:text>(function(str, starts){ + if (starts === '') return true; + if (str == null || starts == null) return false; + str = String(str); starts = String(starts); + return str.length >= starts.length && str.slice(0, starts.length) === starts; + })(</xsl:text>Var<xsl:value-of select="regex-group(3)"/>, Var<xsl:value-of select="regex-group(1)"/><xsl:text>)</xsl:text> --> +<xsl:text>(function(str, starts){if (starts === '') return true;if (str == null || starts == null) return false;str = String(str); starts = String(starts);return str.length >= starts.length && str.slice(0, starts.length) === starts;})(</xsl:text>Var<xsl:value-of select="regex-group(3)"/>, Var<xsl:value-of select="regex-group(1)"/><xsl:text>)</xsl:text> + </xsl:matching-substring> + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:inState"> + <xsl:attribute name="cond">In('<xsl:value-of select="."/>')</xsl:attribute> +</xsl:template> + +<!-- returns a value that cannot be converted into a Boolean --> +<xsl:template match="//@conf:nonBoolean"> + <xsl:attribute name="cond">return</xsl:attribute> +</xsl:template> + +<!-- true if id has a value --> +<xsl:template match="//@conf:isBound"> + <xsl:attribute name="cond">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- return true if specified var has been created but is not bound --> +<xsl:template match="//@conf:unboundVar"> + <xsl:attribute name="cond">typeof Var<xsl:value-of select="." /> === 'undefined' </xsl:attribute> +</xsl:template> + +<!-- true if system var has a value --> +<xsl:template match="//@conf:systemVarIsBound"> + <xsl:attribute name="cond"><xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- true if id does not have a value --> +<xsl:template match="//@conf:noValue"> + <xsl:attribute name="cond">!Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- always returns true --> +<xsl:template match="//@conf:true"> + <xsl:attribute name="cond">true</xsl:attribute> +</xsl:template> + +<!-- always returns false --> +<xsl:template match="//@conf:false"> + <xsl:attribute name="cond">false</xsl:attribute> +</xsl:template> + +<!-- returns true if all the required fields of _event are bound --> +<xsl:template match="//@conf:eventFieldsAreBound"> + <xsl:attribute name="cond">'name' in _event && 'type' in _event && 'sendid' in _event && 'origin' in _event && 'invokeid' && 'data' in _event</xsl:attribute> +</xsl:template> + +<!-- returns true if _event.data contains the specified item --> +<xsl:template match="//@conf:eventDataHasField"> + <xsl:attribute name="cond"><xsl:value-of select="."/> in _event.data</xsl:attribute> +</xsl:template> + +<!-- returns true if specified field of _event has no value --> +<xsl:template match="//@conf:eventFieldHasNoValue"> + <xsl:attribute name="cond">_event.<xsl:value-of select="." /> == null</xsl:attribute> +</xsl:template> + +<!-- true if the language of _event matches the processor's datamodel --> +<xsl:template match="//@conf:eventLanguageMatchesDatamodel"> + <xsl:attribute name="cond"> _event.language == 'ecmascript'</xsl:attribute> +</xsl:template> + +<!-- true if _event was delivered on the specified i/o processor --> +<xsl:template match="//@conf:originTypeEq"> + <xsl:attribute name="cond"> _event.origintype == '<xsl:value-of select="."/>'</xsl:attribute> +</xsl:template> + + + + +<!-- scripting --> + +<xsl:template match="conf:script"> + <script xmlns="http://www.w3.org/2005/07/scxml">var Var1 = 1</script> +</xsl:template> + + +<xsl:template match="//@conf:scriptGoodSrc"> + <xsl:attribute name="src">D:\W3C\SCXMLTests\test300.js</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:scriptBadSrc"> + <xsl:attribute name="src">D:\foo</xsl:attribute> +</xsl:template> + +<!-- sends an event back to the sender of the current event --> +<xsl:template match="conf:sendToSender"> + <send xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="event"><xsl:value-of select="@name" /></xsl:attribute> + <xsl:attribute name="targetexpr">_event.origin</xsl:attribute> + <xsl:attribute name="typeexpr">_event.origintype</xsl:attribute> + </send> +</xsl:template> + +<!-- foreach --> +<!-- this should produce an array containing 1 2 3 in that order --> +<xsl:template match="//conf:array123">[1,2,3]</xsl:template> + +<!-- this uses the value of the indicated variable as the 'array' attribute --> +<xsl:template match="//@conf:arrayVar"> + <xsl:attribute name="array">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- in Python, this is the same as arrayVar --> +<xsl:template match="//@conf:arrayTextVar"> + <xsl:attribute name="array">Var<xsl:value-of select="."/></xsl:attribute> +</xsl:template> + + +<!-- this should produce expr that yields an array containing 1 2 3 in that order --> +<xsl:template match="//@conf:arrayExpr123"> + <xsl:attribute name="expr">1, 2, 3]</xsl:attribute> +</xsl:template> + +<!-- this should yield an expr that evaluates to something that is not a valid array --> +<xsl:template match="//@conf:illegalArray"> + <xsl:attribute name="expr">7</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:item"> + <xsl:attribute name="item">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- this should return something that cannot be an variable name --> +<xsl:template match="//@conf:illegalItem"> + <xsl:attribute name="item">'continue'</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:index"> + <xsl:attribute name="index">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- this should add an extra item onto the end of the specified array, which +is of the same type as array123 --> +<xsl:template match="conf:extendArray"> + <assign xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="location">Var<xsl:value-of select="@id"/></xsl:attribute> + <xsl:attribute name="expr">[].concat(Var<xsl:value-of select="@id"/>, [4])</xsl:attribute> + </assign> + </xsl:template> + +<!-- this should create a multidimensional array all of whose cells are set to the specified value. Not +currently used for any tests --> +<xsl:template match="//@conf:multiDimensionalArrayExpr"> + <xsl:attribute name="expr">[[<xsl:value-of select="."/>,<xsl:value-of select="."/>],[<xsl:value-of select="."/>,<xsl:value-of select="."/>]]</xsl:attribute> +</xsl:template> + + +<!-- this should create a <foreach> statement that increments the values of the specified array. Not +currently used for any tests --> +<xsl:template match="conf:incrementArray"> + <xsl:variable name="targetArray">Var<xsl:value-of select="@id"/></xsl:variable> +<foreach xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="item">item</xsl:attribute> + <xsl:attribute name="index">index</xsl:attribute> + <xsl:attribute name="array"><xsl:value-of select="$targetArray"/></xsl:attribute> +<script> +<xsl:value-of select="$targetArray"/>[index][0] = <xsl:value-of select="$targetArray"/>[index][0] + 1 +<xsl:value-of select="$targetArray"/>[index][1] = <xsl:value-of select="$targetArray"/>[index][1] + 1 +</script> +</foreach> +</xsl:template> +<!-- this should return true iff each cell in the specified multidimensional array has the specified value. Not +currently used for any tests --> +<xsl:template match="//@conf:arrayVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)(\W+)(.*)"> + <xsl:matching-substring> + <xsl:variable name="targetArray">Var<xsl:value-of select="regex-group(1)"/></xsl:variable> + <xsl:variable name="value"><xsl:value-of select="regex-group(3)"/></xsl:variable> +<xsl:value-of select="$targetArray"/>[0][0]== <xsl:value-of select="$value"/> && <xsl:value-of select="$targetArray"/>[0][1] == <xsl:value-of select="$value"/> && <xsl:value-of select="$targetArray"/>[1][0] == <xsl:value-of select="$value"/> && <xsl:value-of select="$targetArray"/>[1][1] == <xsl:value-of select="$value"/> +</xsl:matching-substring> + + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- SITE SPECIFIC INFORMATION FOR BASIC HTTP EVENT I/O PROCESSOR +This template must be edited by each site that expects to test the Basic HTTP Event I/O +processor. Other templates for the Basic HTTP Event I/O tests are below it --> + +<xsl:template match="//@conf:testOnServer"> + <xsl:attribute name="target">SITE_SPECIFIC_ADDRESS<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- use this template to import or set up anything you need for the code in +the basic http tests. In the case of python, we have to import the regexp module.--> +<xsl:template match="conf:setUpHTTPTest"> +<!-- <script xmlns="http://www.w3.org/2005/07/scxml">import re</script> --> +</xsl:template> + +<!-- return an expression evaluating to the basic http access URI --> +<xsl:template match="//@conf:basicHTTPAccessURI"> + <xsl:attribute name="expr">_ioprocessors['basichttp']['location']</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:basicHTTPAccessURITarget"> + <xsl:attribute name="targetexpr">_ioprocessors['basichttp']['location']</xsl:attribute> +</xsl:template> + +<!-- generate an cond that evaluates to true if POST was used to send the message --> +<xsl:template match="//@conf:methodIsPost"> + <xsl:attribute name="cond">_event.raw.search('POST') !== -1</xsl:attribute> +</xsl:template> + +<!-- generate a namelist attribute containing all the ids listed in the attribute's value --> +<xsl:template match="//@conf:multipleNamelist"> + <xsl:attribute name="namelist"> + <xsl:analyze-string select="." regex="([0-9]+)"> +<xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/><xsl:text>
</xsl:text></xsl:matching-substring> +</xsl:analyze-string> +</xsl:attribute> +</xsl:template> + +<!-- generate a cond that evaluates to true if the event is external --> +<xsl:template match="//@conf:eventIsExternal"> + <xsl:attribute name="cond">_event.type === 'external'</xsl:attribute> +</xsl:template> + +<!-- returns true if _event/raw contains the var with the specified value --> +<xsl:template match="//@conf:eventIdParamHasValue"> + <xsl:attribute name="cond"><xsl:analyze-string select="." regex="(\S+)(\s+)(\S+)"> +<xsl:matching-substring>_event.raw.search(/Var<xsl:value-of select="regex-group(1)"/>=<xsl:value-of select="regex-group(3)"/>/) !== -1</xsl:matching-substring></xsl:analyze-string></xsl:attribute> +</xsl:template> + +<!-- returns true if _event/raw contains the param with the specified value --> +<xsl:template match="//@conf:eventNamedParamHasValue"> + <xsl:attribute name="cond"><xsl:analyze-string select="." regex="(\S+)(\s+)(\S+)"> + <xsl:matching-substring>_event.raw.search(/Var<xsl:value-of select="regex-group(1)"/>=<xsl:value-of select="regex-group(3)"/>/) !== -1</xsl:matching-substring></xsl:analyze-string></xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:messageBodyEquals"> + <xsl:attribute name="cond">_event.raw.search(/<xsl:value-of select="."/>/) !== -1</xsl:attribute> +</xsl:template> + + +<!-- the following templates produce an expr that extracts the relevant item from _event.raw --> +<xsl:template match="//@conf:getNamedParamVal"> + <xsl:attribute name="expr">_event.raw.match(/<xsl:value-of select="."/>=(\S+)$/)[1]</xsl:attribute> +</xsl:template> + +<!-- if input is 1, find param Var1, etc. --> +<xsl:template match="//@conf:getIDParamVal"> + <xsl:attribute name="expr">_event.raw.match(/Var<xsl:value-of select="."/>=(\S+)$/)[1]</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:getNthParamName"> + <xsl:attribute name="expr">txt.match(/\n\n(.*)/)[2].split('&')[<xsl:value-of select="."/>].split('=')[0]</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:getNthParamVal"> + <xsl:attribute name="expr">txt.match(/\n\n(.*)/)[2].split('&')[<xsl:value-of select="."/>].split('=')[1]</xsl:attribute> +</xsl:template> + +<!-- this should produce an 'expr' that evaluates to a valid SCXML Message structure --> +<xsl:template match="//@conf:scxmlEventExpr"> + <xsl:attribute name="expr">'<message source="' + _ioprocessors['basichttp'] + '"' ++ 'xmlns:scxml="http://www.w3.org/2005/07/scxml" version="1.0" xmlns:xsi=:http://www.w3.org/2001/XMLSchema-instance" +xsi:schemaLocation="http://www.w3.org/2005/07/scxml scxml-message.xsd" sourcetype=:scxml"' ++' 'name="name"' + '"' + <xsl:value-of select="."/> + '"' + />'</xsl:attribute> + </xsl:template> + +<!-- this should produce a <content> tag containing material to use as the message body. This +content must include the address, so the far side can send a response back to us --> +<xsl:template match="conf:msgContent"> +<content xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="expr">'address=' + _ioprocessors['basichttp'] + "'"</xsl:attribute> + </content> +</xsl:template> + +<!-- this should produce a test on _event.raw that checks whether the body matches the +expression defined in the previous template. This may need to be tightened up because +it allows anything after the = --> +<xsl:template match="//@conf:msgIsBody"> + <xsl:attribute name="cond">_event.raw.match(/\n\naddress=(.*)$/)</xsl:attribute> +</xsl:template> +</xsl:stylesheet>
\ No newline at end of file diff --git a/test/samples/w3c/confXPath.xsl b/test/samples/w3c/confXPath.xsl new file mode 100644 index 0000000..514752a --- /dev/null +++ b/test/samples/w3c/confXPath.xsl @@ -0,0 +1,630 @@ +<?xml version="1.0"?> +<!-- Copyright 1998-2003 W3C (MIT, ERCIM, Keio), All Rights Reserved. See http://www.w3.org/Consortium/Legal/. --> +<xsl:stylesheet + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:conf="http://www.w3.org/2005/scxml-conformance" + version="2.0"> + + + + +<!-- Copy everything that doesn't match other rules --> +<xsl:template match="/ | @* | node()"> + <xsl:copy> + <xsl:apply-templates select="@* | node()"/> + </xsl:copy> +</xsl:template> + +<!-- Success criteria --> + +<xsl:template match="//@conf:targetpass"> + <xsl:attribute name="target">pass</xsl:attribute> +</xsl:template> + +<xsl:template match="conf:pass"> + <final xmlns="http://www.w3.org/2005/07/scxml" id="pass"> + <onentry> + <log label="Outcome" expr="'pass'"/> + </onentry> + </final> +</xsl:template> + +<!-- Failure criteria --> + +<xsl:template match="//@conf:targetfail"> + <xsl:attribute name="target">fail</xsl:attribute> +</xsl:template> + +<xsl:template match="conf:fail"> + <final xmlns="http://www.w3.org/2005/07/scxml" id="fail"> + <onentry> + <log label="Outcome" expr="'fail'"/> + </onentry> +</final> +</xsl:template> + +<!-- datamodel --> +<xsl:template match="//@conf:datamodel"> + <xsl:attribute name="datamodel">xpath</xsl:attribute> +</xsl:template> + + +<!-- creates id for <data> element, etc. --> +<xsl:template match="//@conf:id"> + <xsl:attribute name="id">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + + +<!-- creates name for <param>, etc. --> +<xsl:template match="//@conf:name"> + <xsl:attribute name="name">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + + +<!-- creates location for <assign>, etc. --> +<xsl:template match="//@conf:location"> + <xsl:attribute name="location">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- uses system var as location for <assign>, etc. --> +<xsl:template match="//@conf:systemVarLocation"> + <xsl:attribute name="location">$<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:expr"> + <xsl:attribute name="expr"><xsl:value-of select="." /></xsl:attribute> +</xsl:template> + + +<!-- expr is quoted --> +<xsl:template match="//@conf:quoteExpr"> + <xsl:attribute name="expr">'<xsl:value-of select="." />'</xsl:attribute> +</xsl:template> + +<!-- targetexpr is the corresponding ID --> +<xsl:template match="//@conf:targetVar"> + <xsl:attribute name="targetexpr">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- an expr that yields the text child of a variable --> +<xsl:template match="//@conf:varExpr"> + <xsl:attribute name="expr">$Var<xsl:value-of select="." />/text()</xsl:attribute> +</xsl:template> + + + +<!-- an expr that yields the children of a variable --> +<xsl:template match="//@conf:varChildExpr"> + <xsl:attribute name="expr">$Var<xsl:value-of select="." />/*</xsl:attribute> +</xsl:template> + +<!-- an expr that is the value of a system variable --> +<xsl:template match="//@conf:systemVarExpr"> + <xsl:attribute name="expr">$<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + + +<!-- an expr that is the value of a non-existent substructure of a variable --> +<xsl:template match="//@conf:varNonexistentStruct"> + <xsl:attribute name="expr">$Var<xsl:value-of select="." />.bar</xsl:attribute> +</xsl:template> + + +<!-- this should return a value that cannot be assigned to a var. --> +<xsl:template match="//@conf:illegalExpr"> + <xsl:attribute name="expr">!1</xsl:attribute> +</xsl:template> + +<!-- this should return a simple scxml script that exits as soon as it's invoked. +We assume that this script won't undergo schema validation, so we keep it concise --> +<xsl:template match="//@conf:scxmlExpr"> + <xsl:attribute name="expr">string('<scxml><final/></scxml>')</xsl:attribute> +</xsl:template> + + +<!-- this should add 1 to the value of the specified variable --> +<xsl:template match="conf:incrementID"> + <assign xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="location">$Var<xsl:value-of select="@id"/></xsl:attribute> + <xsl:attribute name="expr">$Var<xsl:value-of select="@id"/> + 1</xsl:attribute> + </assign> + </xsl:template> + + <!-- this should concatenate the value of the id2 to id1 and assign the result to id1 --> +<xsl:template match="conf:concatVars"> + <assign xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="location">$Var<xsl:value-of select="@id1"/></xsl:attribute> + <xsl:attribute name="expr">concat($Var<xsl:value-of select="@id1"/>, $Var<xsl:value-of select="@id2"/>)</xsl:attribute> + </assign> + </xsl:template> + +<!-- assigns the sum of the values of two vars to thefirst var--> +<xsl:template match="//conf:sumVars"> + <assign xmlns="http://www.w3.org/2005/07/scxml"> +<xsl:attribute name="location">$Var<xsl:value-of select="@id1"/></xsl:attribute> +<xsl:attribute name="expr">$Var<xsl:value-of select="@id1"/>/text() + $Var<xsl:value-of select="@id2"/>/text()</xsl:attribute> + </assign> + </xsl:template> + +<!-- foreach --> +<!-- this should produce literal representation of an array containing 1 2 3 in that order --> +<xsl:template match="//conf:array123"> +<node xmlns="">1</node><node xmlns="">2</node><node xmlns="">3</node> +</xsl:template> + +<!-- this uses the children of the indicated variable as the 'array' attribute --> +<xsl:template match="//@conf:arrayVar"> + <xsl:attribute name="array">$Var<xsl:value-of select="."/>/*</xsl:attribute> +</xsl:template> + +<!-- this uses the text child of the indicated variable as the 'array' attribute --> +<xsl:template match="//@conf:arrayTextVar"> + <xsl:attribute name="array">$Var<xsl:value-of select="."/>/text()</xsl:attribute> +</xsl:template> + +<!-- this should yield an expr that evaluates to something that is not a valid array --> +<xsl:template match="//@conf:illegalArray"> + <xsl:attribute name="expr">(</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:item"> + <xsl:attribute name="item">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- this should return something that cannot be an variable name --> +<xsl:template match="//@conf:illegalItem"> + <xsl:attribute name="item">..</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:index"> + <xsl:attribute name="index">Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- this should add items onto the end of the specified array, which +is of the same type as array123 --> +<xsl:template match="conf:extendArray"> + <assign xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="type">lastchild</xsl:attribute> + <xsl:attribute name="location">$Var<xsl:value-of select="@id"/></xsl:attribute> + <xsl:attribute name="expr">$Var<xsl:value-of select="@id"/>/*</xsl:attribute> + </assign> +</xsl:template> + +<xsl:template match="//conf:illegalContent"> + <content xmlns="http://www.w3.org/2005/07/scxml"> xyz </content> +</xsl:template> + +<!-- a content element whose value is the string 'foo' --> +<xsl:template match="//conf:contentFoo"> + <content xmlns="http://www.w3.org/2005/07/scxml">foo</content> +</xsl:template> + + + +<!-- this returns something that is guaranteed not to be the ID of the current session --> +<xsl:template match="//@conf:invalidSessionID"> + <xsl:attribute name="expr">27</xsl:attribute> +</xsl:template> + +<!-- this returns something that is guaranteed not to be a valid event I/O processor --> +<xsl:template match="//@conf:invalidSendType"> + <xsl:attribute name="type">27</xsl:attribute> +</xsl:template> + +<!-- same value in an expr --> +<xsl:template match="//@conf:invalidSendTypeExpr"> + <xsl:attribute name="expr">27</xsl:attribute> +</xsl:template> + +<!-- templates for the expr versions of the send attributes --> + +<!-- eventexpr takes the value of the specified variable --> +<xsl:template match="//@conf:eventExpr"> + <xsl:attribute name="eventexpr">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- targetexpr takes the value of the specified variable --> +<xsl:template match="//@conf:targetExpr"> + <xsl:attribute name="targetexpr">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- typeexpr takes the value of the specified variable --> +<xsl:template match="//@conf:typeExpr"> + <xsl:attribute name="typeexpr">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- delayexpr takes the value of the specified variable --> +<xsl:template match="//@conf:delayExpr"> + <xsl:attribute name="delayexpr">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- the specified variable is used as idlocation --> +<xsl:template match="//@conf:idlocation"> + <xsl:attribute name="idlocation">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- the specified variable is used as sendidexpr --> +<xsl:template match="//@conf:sendIDExpr"> + <xsl:attribute name="sendidexpr">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- the specified variable is used as srcexpr --> +<xsl:template match="//@conf:srcExpr"> + <xsl:attribute name="srcexpr">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- the specified variable is used as namelist --> +<xsl:template match="//@conf:namelist"> + <xsl:attribute name="namelist">$Var<xsl:value-of select="." /></xsl:attribute> +</xsl:template> + +<!-- exprs that return the value of the event fields --> + +<xsl:template match="//@conf:eventName"> + <xsl:attribute name="expr">$_event/name/text()</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:eventType"> + <xsl:attribute name="expr">$_event/type/text()</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:eventSendid"> + <xsl:attribute name="expr">$_event/sendid/text()</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:eventField"> + <xsl:attribute name="expr">$_event/<xsl:value-of select="."/>/text()</xsl:attribute> +</xsl:template> + +<!-- returns the raw message structure as a string --> +<xsl:template match="//@conf:eventRaw"> + <xsl:attribute name="expr">$_event/raw/text()</xsl:attribute> +</xsl:template> + +<!-- returns the value of the specified item in _event.data --> +<xsl:template match="//@conf:eventDataFieldValue"> + <xsl:attribute name="expr">$_event/data/data[@id='<xsl:value-of select="."/>']/text()</xsl:attribute> +</xsl:template> + +<!-- returns the value of a KVP specified by <param> from _event.data --> +<xsl:template match="//@conf:eventDataParamValue"> + <xsl:attribute name="expr">$_event/data/data[@id='<xsl:value-of select="."/>']/text()</xsl:attribute> +</xsl:template> + +<!-- returns the value of a KVP specified by Namelist from _event.data --> +<xsl:template match="//@conf:eventDataNamelistValue"> + <xsl:attribute name="expr">$_event/data/data[@id='<xsl:value-of select="."/>']/data/text()</xsl:attribute> +</xsl:template> + +<!-- returns the location of the scxml event i/o processor --> +<xsl:template match="//@conf:scxmlEventIOLocation"> + <xsl:attribute name="expr">$_ioprocessors/processor[@name="http://www.w3.org/TR/scxml/#SCXMLProcessor"]/location/text()</xsl:attribute> +</xsl:template> + +<!-- to test the BasicHTTP Event I/O processor --> + + + +<!-- return an expression evaluating to the basic http access URI --> +<xsl:template match="//@conf:basicHTTPAccessURI"> + <xsl:attribute name="expr">_ioprocessors/processor[@name="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"]/location/text()</xsl:attribute> +</xsl:template> + +<!-- return a targetexpr evaluating to the basic http access URI --> +<xsl:template match="//@conf:basicHTTPAccessURITarget"> + <xsl:attribute name="targetexpr">$_ioprocessors/processor[@name="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor"]/location/text()</xsl:attribute> +</xsl:template> + +<!-- generate an cond that evaluates to true if POST was used to send the message --> +<xsl:template match="//@conf:methodIsPost"> + <xsl:attribute name="cond">contains($_event/raw, 'POST')</xsl:attribute> +</xsl:template> + +<!-- generate a namelist attribute containing all the ids listed in the attribute's value --> +<xsl:template match="//@conf:multipleNamelist"> + <xsl:attribute name="namelist"> + <xsl:analyze-string select="." regex="([0-9]+)"> +<xsl:matching-substring>Var<xsl:value-of select="regex-group(1)"/><xsl:text>
</xsl:text></xsl:matching-substring> +</xsl:analyze-string> +</xsl:attribute> +</xsl:template> + +<!-- generate a cond that evaluates to true if the event is external --> +<xsl:template match="//@conf:eventIsExternal"> + <xsl:attribute name="cond">_event.type == 'external'</xsl:attribute> +</xsl:template> + + + +<!-- the following templates produce an expr that extracts the relevant item from _event.raw --> +<!-- returns true if _event/raw contains the var with the specified value --> +<xsl:template match="//@conf:eventIdParamHasValue"> + <xsl:attribute name="cond"><xsl:analyze-string select="." regex="([0-9]+)(\s+)(\S+)"> +<xsl:matching-substring>contains($_event/raw, 'Var<xsl:value-of select="regex-group(1)"/>=<xsl:value-of select="regex-group(3)"/>')</xsl:matching-substring></xsl:analyze-string></xsl:attribute> +</xsl:template> + +<!-- returns true if _event/raw contains the param with the specified value --> +<xsl:template match="//@conf:eventNamedParamHasValue"> + <xsl:attribute name="cond"><xsl:analyze-string select="." regex="([0-9]+)(\s+)(\S+)"> +<xsl:matching-substring>contains($_event/raw, '<xsl:value-of select="regex-group(1)"/>=<xsl:value-of select="regex-group(3)"/>')</xsl:matching-substring></xsl:analyze-string></xsl:attribute> +</xsl:template> + +<!-- Should return true if the body of _event.raw equals the specified value. This is too weak because +it tests only that the specified string is in _event.raw, not that it is the whole body. I don't +know if we can make this strong in XPath 1.0 --> +<xsl:template match="//@conf:messageBodyEquals"> + <xsl:attribute name="cond">contains($_event/raw, <xsl:value-of select="."/>)</xsl:attribute> +</xsl:template> + + +<!-- the following templates produce an expr that extracts the relevant item from _event.raw --> +<xsl:template match="//@conf:getNamedParamVal"> + <xsl:attribute name="expr">re.search('<xsl:value-of select="."/>=(\S+)$', _event.raw).groups()[0]</xsl:attribute> +</xsl:template> + +<!-- if input is 1, find param Var1, etc. --> +<xsl:template match="//@conf:getIDParamVal"> + <xsl:attribute name="expr">substring-before(substring-after('Var<xsl:value-of select="."/>=', $_event/raw), '&')</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:getNthParamName"> + <xsl:attribute name="expr">re.search('\n\n(.*)', txt).group(1).split('&')[<xsl:value-of select="."/>].split('=')[0]</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:getNthParamVal"> + <xsl:attribute name="expr">re.search('\n\n(.*)', txt).group(1).split('&')[<xsl:value-of select="."/>].split('=')[1]</xsl:attribute> +</xsl:template> + +<!-- transition conditions --> +<!-- test that given var has specific value. The value expr is evaluated --> +<xsl:template match="//@conf:idVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> + <xsl:matching-substring>$Var<xsl:value-of select="regex-group(1)"/><xsl:text>/text() </xsl:text> + <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> + <xsl:choose> + <xsl:when test="$op='='">=</xsl:when> + <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise> + </xsl:choose> + <xsl:value-of select="regex-group(3)"/> + </xsl:matching-substring> + + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- the value is quoted --> +<xsl:template match="//@conf:idQuoteVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> +<xsl:matching-substring>$Var<xsl:value-of select="regex-group(1)"/><xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> +<xsl:choose> +<xsl:when test="$op='=='">=</xsl:when> +<xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise></xsl:choose>'<xsl:value-of select="regex-group(3)"/>'</xsl:matching-substring> +</xsl:analyze-string> +</xsl:attribute> +</xsl:template> + +<!-- test on the value of two vars --> +<xsl:template match="//@conf:compareIDVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)([0-9+])"> + <xsl:matching-substring>$Var<xsl:value-of select="regex-group(1)"/><xsl:text>/text() </xsl:text> + <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> + <xsl:choose> + <xsl:when test="$op='='">=</xsl:when> + <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise> + </xsl:choose>$Var<xsl:value-of select="regex-group(3)"/><xsl:text>/text() </xsl:text> + </xsl:matching-substring> + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- test that given var whose value was passed in via namelist has specific value. The value expr is evaluated --> +<xsl:template match="//@conf:namelistIdVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> + <xsl:matching-substring>$Var<xsl:value-of select="regex-group(1)"/><xsl:text>/data/text() </xsl:text> + <xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> + <xsl:choose> + <xsl:when test="$op='='">=</xsl:when> + <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise> + </xsl:choose> + <xsl:value-of select="regex-group(3)"/> + </xsl:matching-substring> + + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- return true if variable matches value of system var (var number is first arg, system var name +is the second argument --> +<xsl:template match="//@conf:idSystemVarVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> +<xsl:matching-substring>$Var<xsl:value-of select="regex-group(1)"/><xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> +<xsl:choose> +<xsl:when test="$op='=='">=</xsl:when> +<xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise></xsl:choose>$<xsl:value-of select="regex-group(3)"/></xsl:matching-substring> +</xsl:analyze-string> +</xsl:attribute> +</xsl:template> + +<!-- test that the event's name fieldhas the value specified --> +<xsl:template match="//@conf:eventNameVal"> + <xsl:attribute name="cond">$_event/name = <xsl:text>'</xsl:text><xsl:value-of select="."/><xsl:text>'</xsl:text> + </xsl:attribute> + +</xsl:template> +<!-- returns true if all the required fields of _event are bound --> +<xsl:template match="//@conf:eventFieldsAreBound"> + <xsl:attribute name="cond">$_event/name and $_event/type and $_event/sendid and $_event/origin and $_event/origintype and $_event/invokeid and $_event/data</xsl:attribute> +</xsl:template> + +<!-- returns true if machine is in the state specified --> + +<xsl:template match="//@conf:inState"> + <xsl:attribute name="cond">In('<xsl:value-of select="."/>')</xsl:attribute> +</xsl:template> + +<!-- return true if specified var has been created but has no value --> +<xsl:template match="//@conf:unboundVar"> + <xsl:attribute name="cond">$Var<xsl:value-of select="." /> and not($Var<xsl:value-of select="." />/text()) and not($Var<xsl:value-of select="." />/*)</xsl:attribute> +</xsl:template> + +<!-- return true if the specified key in event.data has the specified value --> +<xsl:template match="//@conf:eventvarVal"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)([=<>]=?)(.*)"> + <xsl:matching-substring>$_event/data/data[@id = 'Var<xsl:value-of select="regex-group(1)"/>']/text()<xsl:variable name="op"><xsl:value-of select="regex-group(2)"/></xsl:variable> + <xsl:choose> + <xsl:when test="$op='='">=</xsl:when> + <xsl:otherwise><xsl:value-of select="$op"/></xsl:otherwise> + </xsl:choose> + <xsl:value-of select="regex-group(3)"/> + </xsl:matching-substring> + + </xsl:analyze-string> + </xsl:attribute> + +</xsl:template> + +<!-- return true if event.data field matches the specified value --> + +<xsl:template match="//@conf:eventdataVal"> + <xsl:attribute name="cond">$_event/data = '<xsl:value-of select="."/>'</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:emptyEventData"> + <xsl:attribute name="cond">not($_event/data/*)</xsl:attribute> +</xsl:template> + +<!-- return true if the _name system var has the specified quoted value --> + +<xsl:template match="//@conf:nameVarVal"> + <xsl:attribute name="cond">$_name/text() = '<xsl:value-of select="."/>'</xsl:attribute> +</xsl:template> + +<!-- returns true if _event.data contains the specified item --> +<xsl:template match="//@conf:eventDataHasField"> + <xsl:attribute name="cond">$_event/data/data[@id=<xsl:value-of select="."/>]</xsl:attribute> +</xsl:template> + +<!-- return true if first var's value is a prefix of the second var's value. Input has form "n m" where n and m are ints.--> +<xsl:template match="//@conf:varPrefix"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="(\w+)(\W)(\w+)"> + <xsl:matching-substring> +contains($Var<xsl:value-of select="regex-group(3)"/>, $Var<xsl:value-of select="regex-group(1)"/><xsl:text>)</xsl:text> + </xsl:matching-substring> + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- true if id has a value --> +<xsl:template match="//@conf:isBound"> + <xsl:attribute name="cond">$Var<xsl:value-of select="." />/* or $Var<xsl:value-of select="." />/text()</xsl:attribute> +</xsl:template> + +<!-- true if id does not have an atomic value --> +<xsl:template match="//@conf:noValue"> + <xsl:attribute name="cond">not($Var<xsl:value-of select="." />/text() or $Var<xsl:value-of select="." />/*)</xsl:attribute> +</xsl:template> + +<!-- true if system var has a value --> +<xsl:template match="//@conf:systemVarIsBound"> + <xsl:attribute name="cond">$<xsl:value-of select="." />/text()</xsl:attribute> +</xsl:template> + +<!-- returns true if specified field of _event has no value --> +<xsl:template match="//@conf:eventFieldHasNoValue"> + <xsl:attribute name="cond">not(string($_event/<xsl:value-of select="." />))</xsl:attribute> +</xsl:template> + +<!-- returns a value that cannot be converted into a Boolean --> +<xsl:template match="//@conf:nonBoolean"> + <xsl:attribute name="cond">==!*</xsl:attribute> +</xsl:template> + +<!-- always returns true --> +<xsl:template match="//@conf:true"> + <xsl:attribute name="cond">true()</xsl:attribute> +</xsl:template> + +<!-- always returns false --> +<xsl:template match="//@conf:false"> + <xsl:attribute name="cond">0>1</xsl:attribute> +</xsl:template> + + + +<!-- this should return an illegal target for <send> causing a send error to be raised --> +<xsl:template match="//@conf:illegalTarget"> + <xsl:attribute name="target">baz</xsl:attribute> +</xsl:template> + +<!-- this returns an legal, but unreachable, target for <send> causing a send error to be raised --> +<xsl:template match="//@conf:unreachableTarget"> + <xsl:attribute name="target">#_scxml_foo</xsl:attribute> +</xsl:template> + +<!-- true if the two vars/ids have the same value --> +<xsl:template match="//@conf:VarEqVar"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)(\W+)([0-9]+)"> + <xsl:matching-substring>$Var<xsl:value-of select="regex-group(1)"/>/text()=$Var<xsl:value-of select="regex-group(3)"/>/text()</xsl:matching-substring> + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- true if the two vars/ids have the same value, which is a structure, not atomic --> +<xsl:template match="//@conf:VarEqVarStruct"> + <xsl:attribute name="cond"> + <xsl:analyze-string select="." + regex="([0-9]+)(\W+)([0-9]+)"> + <xsl:matching-substring>$Var<xsl:value-of select="regex-group(1)"/>=$Var<xsl:value-of select="regex-group(3)"/></xsl:matching-substring> + </xsl:analyze-string> + </xsl:attribute> +</xsl:template> + +<!-- true if _event was delivered on the specified i/o processor --> +<xsl:template match="//@conf:originTypeEq"> + <xsl:attribute name="cond">$_event/origintype/text() = '<xsl:value-of select="."/>'</xsl:attribute> +</xsl:template> + + +<!-- scripting is not supported in Xpath, so not sure what to put here. Implementers +should know not to bother to run these tests--> + +<xsl:template match="conf:script"> + <script xmlns="http://www.w3.org/2005/07/scxml"> + </script> +</xsl:template> + + +<xsl:template match="//@conf:scriptGoodSrc"> + <xsl:attribute name="src">D:\W3C\SCXMLTests\test300.py</xsl:attribute> +</xsl:template> + +<xsl:template match="//@conf:scriptBadSrc"> + <xsl:attribute name="src">D:\foo</xsl:attribute> +</xsl:template> + +<!-- sends an event back to the sender of the current event --> +<xsl:template match="conf:sendToSender"> + <send xmlns="http://www.w3.org/2005/07/scxml"> + <xsl:attribute name="event"><xsl:value-of select="@name" /></xsl:attribute> + <xsl:attribute name="targetexpr">$_event/origin/text()</xsl:attribute> + <xsl:attribute name="typeexpr">$_event/origintype/text()</xsl:attribute> + </send> +</xsl:template> + +</xsl:stylesheet>
\ No newline at end of file diff --git a/test/samples/w3c/convert-tests.pl b/test/samples/w3c/convert-tests.pl new file mode 100755 index 0000000..9c91e3c --- /dev/null +++ b/test/samples/w3c/convert-tests.pl @@ -0,0 +1,37 @@ +#!/opt/local/bin/perl -w + +use strict; + +use XML::LibXSLT; +use XML::LibXML; +use Data::Dumper; + +my $xslt = XML::LibXSLT->new(); +my $xsl = shift || 'confEcma.xsl'; + +opendir(my $testDir, "tests") or die($!); +opendir(my $txmlDir, "txml") or die($!); +while(readdir $txmlDir) { + next unless /txml$/; + my $baseName = $_; + my $txmlFile = 'txml/'.$_; + + my $source = XML::LibXML->load_xml(location => $txmlFile) or die($!); + my $style_doc = XML::LibXML->load_xml(location => $xsl, no_cdata=>1) or die($!); + + my $stylesheet = $xslt->parse_stylesheet($style_doc) or die($!); + my $results = $stylesheet->transform($source) or die($!); + + open(my $json, '>', "tests/".$baseName.".json") or die($!); + print $json <<EOF; +{ + "initialConfiguration" : ["pass"], + "events" : [] +} +EOF + close($json); + + open(my $scxml, '>', "tests/".$baseName.".scxml") or die($!); + print $scxml $stylesheet->output_as_bytes($results); + close($scxml); +} diff --git a/test/samples/w3c/edit-profile-config.scxml b/test/samples/w3c/edit-profile-config.scxml deleted file mode 100644 index 2f8753e..0000000 --- a/test/samples/w3c/edit-profile-config.scxml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - Dialog definitions for Shale Use Cases Example Web Application - written out as SCXML to demonstrate use of Commons SCXML as one - of Shale's Dialog Manager implementations. - For details, see: http://shale.apache.org/shale-dialog-scxml/ ---> -<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:my="http://scxml.example.com/" - version="1.0" initial="edit" datamodel="el"> - - <state id="edit"> - <initial> - <transition target="setup"/> - </initial> - - <!-- global transitions (within state "edit") --> - <transition event="faces.outcome" cond="${outcome eq 'cancel'}" target="cancel"/> - <transition event="faces.outcome" cond="${outcome eq 'finish'}" target="finish"/> - - <state id="setup"> - <onentry> - <my:var name="setupOutcome" expr="#{profile$edit.setup}" /> - </onentry> - <transition cond="${setupOutcome eq 'success'}" target="page1"/> - </state> - - <state id="page1"> - <transition event="faces.outcome" cond="${outcome eq 'next'}" target="page2"/> - </state> - - <state id="page2"> - - <transition event="faces.outcome" cond="${outcome eq 'previous'}" target="page1"/> - <transition event="faces.outcome" cond="${outcome eq 'next'}" target="page3"/> - - </state> - - <state id="page3"> - <transition event="faces.outcome" cond="${outcome eq 'previous'}" target="page2"/> - <transition event="faces.outcome" cond="${outcome eq 'next'}" target="editExit"/> - </state> - - </state> - - <state id="cancel"> - - <onentry> - <my:var name="cancelOutcome" expr="#{profile$edit.cancel}" /> - </onentry> - <transition cond="${cancelOutcome eq 'success'}" target="editExit"> - <my:var name="outcome" expr="cancel"/> - </transition> - </state> - - <state id="finish"> - - <onentry> - <my:var name="finishOutcome" expr="#{profile$edit.finish}" /> - </onentry> - - <transition cond="${finishOutcome eq 'username'}" target="page1"/> - <transition cond="${finishOutcome eq 'password'}" target="page1"/> - <transition cond="${finishOutcome eq 'success'}" target="editExit"> - <my:var name="outcome" expr="success"/> - </transition> - </state> - - <final id="editExit"/> - -</scxml> diff --git a/test/samples/w3c/log-on-config.scxml b/test/samples/w3c/log-on-config.scxml deleted file mode 100644 index 01f45d6..0000000 --- a/test/samples/w3c/log-on-config.scxml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - Dialog definitions for Shale Use Cases Example Web Application - written out as SCXML to demonstrate use of Commons SCXML as one - of Shale's Dialog Manager implementations. - For details, see: http://shale.apache.org/shale-dialog-scxml/ ---> -<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:my="http://scxml.example.com/" - version="1.0" initial="checkCookie" datamodel="el" > - - <state id="checkCookie"> - <onentry> - <my:var name="cookieOutcome" expr="#{profile$logon.check}" /> - </onentry> - <transition cond="${cookieOutcome eq 'authenticated'}" target="exit"/> - <transition cond="${cookieOutcome eq 'unauthenticated'}" target="logon"/> - - </state> - - <state id="logon"> - <transition event="faces.outcome" cond="${outcome eq 'authenticated'}" target="exit"/> - <transition event="faces.outcome" cond="${outcome eq 'create'}" target="createProfile"/> - </state> - - - <state id="createProfile" src="edit-profile-config.xml" > - <transition event="createProfile.done" cond="${outcome eq 'success' or outcome eq 'cancel'}" target="exit"/> - </state> - - <final id="exit"/> - -</scxml> diff --git a/test/samples/w3c/microwave-01.scxml b/test/samples/w3c/microwave-01.scxml deleted file mode 100644 index 71e2f98..0000000 --- a/test/samples/w3c/microwave-01.scxml +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0"?> -<scxml xmlns="http://www.w3.org/2005/07/scxml" - version="1.0" - datamodel="ecmascript" - initial="off"> - - <!-- trivial 5 second microwave oven example --> - <datamodel> - <data id="cook_time" expr="5"/> - <data id="door_closed" expr="true"/> - <data id="timer" expr="0"/> - </datamodel> - - <state id="off"> - <!-- off state --> - <transition event="turn.on" target="on"/> - </state> - - <state id="on"> - <initial> - <transition target="idle"/> - </initial> - <!-- on/pause state --> - - <transition event="turn.off" target="off"/> - <transition cond="timer >= cook_time" target="off"/> - - <state id="idle"> - <!-- default immediate transition if door is shut --> - <transition cond="door_closed" target="cooking"/> - <transition event="door.close" target="cooking"> - <assign location="door_closed" expr="true"/> - <!-- start cooking --> - </transition> - </state> - - <state id="cooking"> - <transition event="door.open" target="idle"> - <assign location="door_closed" expr="false"/> - </transition> - - <!-- a 'time' event is seen once a second --> - <transition event="time"> - <assign location="timer" expr="timer + 1"/> - </transition> - </state> - - </state> - -</scxml> diff --git a/test/samples/w3c/microwave-02.scxml b/test/samples/w3c/microwave-02.scxml deleted file mode 100644 index a96f1fd..0000000 --- a/test/samples/w3c/microwave-02.scxml +++ /dev/null @@ -1,63 +0,0 @@ -<?xml version="1.0"?> -<scxml xmlns="http://www.w3.org/2005/07/scxml" - version="1.0" - datamodel="ecmascript" - initial="oven"> - - <!-- trivial 5 second microwave oven example --> - <!-- using parallel and In() predicate --> - <datamodel> - <data id="cook_time" expr="5"/> - <data id="door_closed" expr="true"/> - <data id="timer" expr="0"/> - </datamodel> - - <parallel id="oven"> - - <!-- this region tracks the microwave state and timer --> - <state id="engine"> - <transition target="off"/> - - <state id="off"> - <!-- off state --> - <transition event="turn.on" target="on"/> - </state> - - <state id="on"> - <transition target="idle"/> - <!-- on/pause state --> - - <transition event="turn.off" target="off"/> - <transition cond="timer >= cook_time" target="off"/> - - <state id="idle"> - <transition cond="In('closed')" target="cooking"/> - </state> - - <state id="cooking"> - <transition cond="In('open')" target="idle"/> - - <!-- a 'time' event is seen once a second --> - <transition event="time"> - <assign location="timer" expr="timer + 1"/> - </transition> - </state> - </state> - </state> - - <!-- this region tracks the microwave door state --> - <state id="door"> - <initial> - <transition target="closed"/> - </initial> - <state id="closed"> - <transition event="door.open" target="open"/> - </state> - <state id="open"> - <transition event="door.close" target="closed"/> - </state> - </state> - - </parallel> - -</scxml> diff --git a/test/samples/w3c/simple.xml b/test/samples/w3c/simple.xml deleted file mode 100644 index d3badc8..0000000 --- a/test/samples/w3c/simple.xml +++ /dev/null @@ -1,9 +0,0 @@ -<scxml xmlns="http://www.w3.org/2005/07/scxml" - version="1.0" - initial="Main" - datamodel="ecmascript"> - <state /> - <state /> - <state /> - <state /> -</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test144.txml b/test/samples/w3c/txml/test144.txml new file mode 100644 index 0000000..73e50b0 --- /dev/null +++ b/test/samples/w3c/txml/test144.txml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> + +<!-- test that events are inserted into the queue in the order in which they are raised. If +foo occurs before bar, success, otherwise failure --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition event="foo" target="s1"/> + <transition event="*" conf:targetfail=""/> + + </state> + +<state id="s1"> + <transition event="bar" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test147.txml b/test/samples/w3c/txml/test147.txml new file mode 100644 index 0000000..20363a0 --- /dev/null +++ b/test/samples/w3c/txml/test147.txml @@ -0,0 +1,34 @@ +<?xml version="1.0"?> + +<!-- test that the first clause that evaluates to true - and only that clause - is executed. +Only one event should be raised, and it should be bar --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <if conf:false=""> + <raise event="foo"/> + <conf:incrementID id="1"/> + <elseif conf:true=""/> + <raise event="bar"/> + <conf:incrementID id="1"/> + <else/> + <raise event="baz"/> + <conf:incrementID id="1"/> + </if> + <raise event="bat"/> + </onentry> + <transition event="bar" conf:idVal="1=1" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test148.txml b/test/samples/w3c/txml/test148.txml new file mode 100644 index 0000000..8d19e56 --- /dev/null +++ b/test/samples/w3c/txml/test148.txml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> + +<!-- test that the else clause executes if <if> and <elseif> evaluate to false. +Baz should be the only event generated by the <if>. bat is raised to catch the case where the <else> clause +fails and baz is not generated, i.e. it makes sure that the test doesn't hang. --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <if conf:false=""> + <raise event="foo"/> + <conf:incrementID id="1"/> + <elseif conf:false=""/> + <raise event="bar"/> + <conf:incrementID id="1"/> + <else/> + <raise event="baz"/> + <conf:incrementID id="1"/> + </if> + <raise event="bat"/> + </onentry> + <transition event="baz" conf:idVal="1=1" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test149.txml b/test/samples/w3c/txml/test149.txml new file mode 100644 index 0000000..c971eea --- /dev/null +++ b/test/samples/w3c/txml/test149.txml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- test that neither if clause executes, so that bat is the only event raised. --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <if conf:false=""> + <raise event="foo"/> + <conf:incrementID id="1"/> + <elseif conf:false=""/> + <raise event="bar"/> + <conf:incrementID id="1"/> + </if> + <raise event="bat"/> + </onentry> + <transition event="bat" conf:idVal="1=0" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test150.txml b/test/samples/w3c/txml/test150.txml new file mode 100644 index 0000000..ff290dd --- /dev/null +++ b/test/samples/w3c/txml/test150.txml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> + +<!-- test that foreach causes a new variable to be declared if 'item' doesn't already exist. Also +test that it will use an existing var if it does exist. --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1"/> + <data conf:id="2"/> + <data conf:id="3"> + <conf:array123/> + </data> + </datamodel> + + <state id="s0"> + <onentry> +<!-- first use declared variables --> + <foreach conf:item="1" conf:index="2" conf:arrayVar="3"/> + <raise event="foo"/> + </onentry> + <transition event="error" conf:targetfail=""/> + <transition event="*" target="s1"/> + </state> + +<state id="s1"> + <onentry> +<!-- now use undeclared variables --> + <foreach conf:item="4" conf:index="5" conf:arrayVar="3"/> + <raise event="bar"/> + </onentry> + <transition event="error" conf:targetfail=""/> + <transition event="*" target="s2"/> + </state> + +<state id="s2"> + <!-- check that var4 is bound --> + <transition conf:isBound="4" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + <conf:pass/> + <conf:fail/> + + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test151.txml b/test/samples/w3c/txml/test151.txml new file mode 100644 index 0000000..6f95692 --- /dev/null +++ b/test/samples/w3c/txml/test151.txml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> + +<!-- test that foreach causes a new variable to be declared if 'item' doesn't already exist. Also +test that it will use an existing var if it does exist. --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1"/> + <data conf:id="2"/> + <data conf:id="3"> + <conf:array123/> + </data> + </datamodel> + + <state id="s0"> + <onentry> +<!-- first use declared variables --> + <foreach conf:item="1" conf:index="2" conf:arrayVar="3"/> + <raise event="foo"/> + </onentry> + <transition event="error" conf:targetfail=""/> + <transition event="*" target="s1"/> + </state> + +<state id="s1"> + <onentry> +<!-- now use undeclared variables --> + <foreach conf:item="4" conf:index="5" conf:arrayVar="3"/> + <raise event="bar"/> + </onentry> + <transition event="error" conf:targetfail=""/> + <transition event="*" target="s2"/> + </state> + +<state id="s2"> + <!-- check that var5 is bound --> + <transition conf:isBound="5" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + <conf:pass/> + <conf:fail/> + + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test152.txml b/test/samples/w3c/txml/test152.txml new file mode 100644 index 0000000..86b50e9 --- /dev/null +++ b/test/samples/w3c/txml/test152.txml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> + +<!-- test that an illegal array or item value causes error.execution and results in executable content +not being executed. --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> + <data conf:id="2"/> + <data conf:id="3"/> + <data conf:id="4" conf:illegalArray=""/> + <data conf:id="5"> + <conf:array123/> + </data> + </datamodel> + + <state id="s0"> + <onentry> +<!-- invalid array, legal item --> + <foreach conf:item="2" conf:index="3" conf:arrayTextVar="4"> + <conf:incrementID id="1"/> + </foreach> + <raise event="foo"/> + </onentry> + <transition event="error.execution" target="s1"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s1"> + <onentry> +<!-- illegal item, legal array --> + <foreach conf:illegalItem="" conf:index="3" conf:arrayVar="5"> + <conf:incrementID id="1"/> + </foreach> + <raise event="bar"/> + </onentry> + <transition event="error.execution" target="s2"/> + <transition event="bar" conf:targetfail=""/> + </state> + +<state id="s2"> + <!-- check that var1 has its original value (so executable content never got executed --> + <transition conf:idVal="1=0" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test153.txml b/test/samples/w3c/txml/test153.txml new file mode 100644 index 0000000..e9f8038 --- /dev/null +++ b/test/samples/w3c/txml/test153.txml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> + +<!-- test that foreach goes over the array in the right order. since the array contains 1 2 3, we compare the current +value with the previous value, which is stored in var1. The current value should always be larger. If +it ever isn't, set Var4 to 0, indicating failure --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> <!-- contains the previous value --> + <data conf:id="2"/> <!-- the item which will contain the current value --> + <data conf:id="3"> + <conf:array123/> + </data> + <data conf:id="4" conf:expr="1"/> <!-- 1 if success, 0 if failure --> + </datamodel> + + <state id="s0"> + <onentry> + <foreach conf:item="2" conf:arrayVar="3"> + <if conf:compareIDVal="1<2"> + <assign conf:location="1" conf:varExpr="2"/> + <else/> + <!-- values are out of order, record failure --> + <assign conf:location="4" conf:expr="0"/> + </if> + </foreach> + </onentry> + + <!-- check that var1 has its original value --> + <transition conf:idVal="4=0" conf:targetfail=""/> + <transition conf:targetpass=""/> + </state> + + <conf:pass/> + <conf:fail/> + + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test155.txml b/test/samples/w3c/txml/test155.txml new file mode 100644 index 0000000..8444442 --- /dev/null +++ b/test/samples/w3c/txml/test155.txml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> + +<!-- test that foreach executes the executable content once for each item in the list '(1,2,3)'. The executable +content sums the items into var1 so it should be 6 at the end --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<datamodel> + <data conf:id="1" conf:expr="0"/> + <data conf:id="2"/> + <data conf:id="3"> + <conf:array123/> + </data> + </datamodel> + + <state id="s0"> + <onentry> + <foreach conf:item="2" conf:arrayVar="3"> + <conf:sumVars id1="1" id2="2"/> + </foreach> + </onentry> + + <transition conf:idVal="1=6" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test156.txml b/test/samples/w3c/txml/test156.txml new file mode 100644 index 0000000..316f879 --- /dev/null +++ b/test/samples/w3c/txml/test156.txml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> + +<!-- test that an error causes the foreach to stop execution. The second piece of executable content +should cause an error, so var1 should be incremented only once --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<datamodel> + <data conf:id="1" conf:expr="0"/> + <data conf:id="2"/> + <data conf:id="3"> + <conf:array123/> + </data> + </datamodel> + + <state id="s0"> + <onentry> + <foreach conf:item="2" conf:arrayVar="3"> + <conf:incrementID id="1"/> + <!-- assign an illegal value to a non-existent var --> + <assign conf:location="5" conf:illegalExpr=""/> + </foreach> + </onentry> + + <transition conf:idVal="1=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test158.txml b/test/samples/w3c/txml/test158.txml new file mode 100644 index 0000000..cff220d --- /dev/null +++ b/test/samples/w3c/txml/test158.txml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> + +<!-- test that executable content executes in document order. if event1 occurs then event2, succeed, otherwise fail --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <raise event="event1"/> + <raise event="event2"/> + </onentry> + <transition event="event1" target="s1"/> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s1"> + <transition event="event2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test159.txml b/test/samples/w3c/txml/test159.txml new file mode 100644 index 0000000..abf1925 --- /dev/null +++ b/test/samples/w3c/txml/test159.txml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> + +<!-- test that any error raised by an element of executable content causes all subsequent elements to be skipped. +The send tag will raise an error so var1 should not be incremented. If it is fail, otherwise succeed --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="thisWillFail" conf:illegaltarget=""/> + <conf:incrementId id="1"/> + </onentry> + <transition conf:idVal="1=1" conf:targetfail=""/> + <transition conf:targetpass=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test172.txml b/test/samples/w3c/txml/test172.txml new file mode 100644 index 0000000..45075a0 --- /dev/null +++ b/test/samples/w3c/txml/test172.txml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- we test that eventexpr uses the current value of var1, not its initial value --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:quoteExpr="event1"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign conf:location="1" conf:quoteExpr="event2"/> + <send conf:eventExpr="1"/> + </onentry> + + <transition event="event2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test173.txml b/test/samples/w3c/txml/test173.txml new file mode 100644 index 0000000..c770856 --- /dev/null +++ b/test/samples/w3c/txml/test173.txml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- we test that targetexpr uses the current value of var1, not its initial value +(If it uses the initial value, it will generate an error. If it uses the current value, event1 will be raised --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:invalidSessionID=""/> + </datamodel> + +<state id="s0"> + <onentry> + <assign conf:location="1" conf:quoteExpr="#_internal"/> + <send conf:targetExpr="1" event="event1"/> + </onentry> + + <transition event="event1" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test174.txml b/test/samples/w3c/txml/test174.txml new file mode 100644 index 0000000..3d33d5b --- /dev/null +++ b/test/samples/w3c/txml/test174.txml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- we test that typeexpr uses the current value of var1, not its initial value +(If it uses the initial value, it will generate an error. If it uses the current value, event1 will be raised --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:invalidSendTypeExpr=""/> + </datamodel> + +<state id="s0"> + <onentry> + <assign conf:location="1" conf:quoteExpr="http://www.w3.org/TR/scxml/#SCXMLEventProcessor"/> + <send conf:typeExpr="1" event="event1"/> + </onentry> + + <transition event="event1" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test175.txml b/test/samples/w3c/txml/test175.txml new file mode 100644 index 0000000..aba7ac4 --- /dev/null +++ b/test/samples/w3c/txml/test175.txml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- we test that delayexpr uses the current value of var1, not its initial value +(If it uses the initial value, event2 will be generated first, before event1. If it uses the current value, +event1 will be raised first. Succeed if event1 occurs before event2, otherwise fail --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:quoteExpr="0s"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign conf:location="1" conf:quoteExpr="3s"/> + <send conf:delayExpr="1" event="event2"/> + <send delay="1s" event="event1"/> + </onentry> + + <transition event="event1" target="s1"/> + <transition event="event2" conf:targetfail=""/> + </state> + +<state id="s1"> + <transition event="event2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test176.txml b/test/samples/w3c/txml/test176.txml new file mode 100644 index 0000000..8d084d4 --- /dev/null +++ b/test/samples/w3c/txml/test176.txml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- we test that <param> uses the current value of var1, not its initial value. If the value of +aParam in event1 is 2 so that var2 gets set to 2, success, otherwise failure --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + <data conf:id="2"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign conf:location="1" conf:expr="2"/> + <send event="event1"> + <param name="aParam" conf:varExpr="1"/> + </send> + </onentry> + + <transition event="event1" target="s1"> + <assign conf:location="2" conf:eventDataFieldValue="aParam"/> + </transition> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s1"> + <transition conf:idVal="2=2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test178.txml b/test/samples/w3c/txml/test178.txml new file mode 100644 index 0000000..de7a334 --- /dev/null +++ b/test/samples/w3c/txml/test178.txml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- we test that multiple key/value pairs are included, even when the keys are the same. +This is a manual test. The tester must look at the log output and verify that both +keys are there. (This test uses the SCXML Event I/O processor, which is the only +one that all platforms must support. It does not specify the message format, so +we cannot test _event.raw directly. Therefore we print it out for visual +inspection.) --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s0"> + <onentry> + <send event="event1"> + <param conf:name="1" conf:expr="2"/> + <param conf:name="1" conf:expr="3"/> + </send> + </onentry> + + <transition event="event1" target="final"> + <log label="_event " conf:eventRaw=""/> + </transition> + <transition event="*" conf:targetfail=""/> + + </state> + + +<final id="final"/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test179.txml b/test/samples/w3c/txml/test179.txml new file mode 100644 index 0000000..02b74f6 --- /dev/null +++ b/test/samples/w3c/txml/test179.txml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- we test that <content> can be used to populate body of a message --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="event1"> + <content>123</content> + </send> + </onentry> + + <transition event="event1" conf:eventdataVal="123" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test183.txml b/test/samples/w3c/txml/test183.txml new file mode 100644 index 0000000..bb6e44a --- /dev/null +++ b/test/samples/w3c/txml/test183.txml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- we test that <send> stores the value of the sendid in idlocation. If it does, +var1 has a value and we pass. Otherwise we fail --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1"/> + + </datamodel> + +<state id="s0"> + <onentry> + <send event="event1" conf:idlocation="1"/> + </onentry> + + <transition conf:isBound="1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test185.txml b/test/samples/w3c/txml/test185.txml new file mode 100644 index 0000000..c036cbf --- /dev/null +++ b/test/samples/w3c/txml/test185.txml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- we test that <send> respects the delay specification. If it does, event1 arrives before event2 + and we pass. Otherwise we fail --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="event2" delay="2s"/> + <send event="event1"/> + </onentry> + + <transition event="event1" target="s1"/> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s1"> + <transition event="event2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test186.txml b/test/samples/w3c/txml/test186.txml new file mode 100644 index 0000000..e91c290 --- /dev/null +++ b/test/samples/w3c/txml/test186.txml @@ -0,0 +1,34 @@ +<?xml version="1.0"?> +<!-- we test that <send> evals its args when it is evaluated, not when the delay interval expires and the +message is actually sent. If it does, aParam will have the value of 1 (even though var1 has been incremented +in the interval.) If var2 ends up == 1, we pass. Otherwise we fail --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + <data conf:id="2"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="event1" delay="2s"> + <param name="aParam" conf:varExpr="1"/> + </send> + <assign conf:location="1" conf:expr="2"/> + </onentry> + + <transition event="event1" target="s1"> + <assign conf:location="2" conf:eventDataFieldValue="aParam"/> + </transition> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s1"> + <transition conf:idVal="2=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test187.txml b/test/samples/w3c/txml/test187.txml new file mode 100644 index 0000000..994a489 --- /dev/null +++ b/test/samples/w3c/txml/test187.txml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- we test that delayed <send> is not sent if the sending session terminates. In this case, +a subscript is invoked which sends the event childToParent delayed by 1 second, and then terminates. The +parent session, should not receive childToParent. If it does, we fail. Otherwise the +10 sec timer expires and we pass --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" > + <onentry> + <send event="timeout" delay="10s"/> + </onentry> + <invoke type="scxml" > + <content> + <!-- exit before the delayed send can execute --> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0"> + <onentry> + <send event="childToParent" target="#_parent" delay="1s"/> + </onentry> + <transition target="subFinal"/> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="childToParent" conf:targetfail=""/> + <transition event="timeout" conf:targetpass=""/> +</state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test194.txml b/test/samples/w3c/txml/test194.txml new file mode 100644 index 0000000..9e660a5 --- /dev/null +++ b/test/samples/w3c/txml/test194.txml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- we test that specifying an illegal target for <send> causes the event error.execution to be raised. If it does, +we succeed. Otherwise we eventually timeout and fail. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <!-- should cause an error --> + <send conf:illegalTarget="" event="event2"/> + <!-- this will get added to the external event queue after the error has been raised --> + <send event="timeout"/> + </onentry> + + <!-- once we've entered the state, we should check for internal events first --> + <transition event="error.execution" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test198.txml b/test/samples/w3c/txml/test198.txml new file mode 100644 index 0000000..706ea93 --- /dev/null +++ b/test/samples/w3c/txml/test198.txml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- we test that if type is not provided <send> uses the scxml event i/o processor. The only way to tell +what processor was used is to look at the origintype of the resulting event --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s0"> + <onentry> + <send event="event1"/> + <send event="timeout"/> + </onentry> + + + <transition event="event1" conf:originTypeEq="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test199.txml b/test/samples/w3c/txml/test199.txml new file mode 100644 index 0000000..dadd5b0 --- /dev/null +++ b/test/samples/w3c/txml/test199.txml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- we test that using an invalid send type results in error.execution --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s0"> + <onentry> + <send conf:invalidSendType="" event="event1"/> + <send event="timeout"/> + </onentry> + + + <transition event="error.execution" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test200.txml b/test/samples/w3c/txml/test200.txml new file mode 100644 index 0000000..4aed203 --- /dev/null +++ b/test/samples/w3c/txml/test200.txml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- we test that the processor supports the scxml event i/o processor --> + + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s0"> + <onentry> + <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" event="event1"/> + <send event="timeout"/> + </onentry> + + + <transition event="event1" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test201.txml b/test/samples/w3c/txml/test201.txml new file mode 100644 index 0000000..c21eb7e --- /dev/null +++ b/test/samples/w3c/txml/test201.txml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- we test that the processor supports the basic http event i/o processor. This is an optional +test since platforms are not required to support basic http event i/o --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s0"> + <onentry> + <send type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor" event="event1"/> + <send event="timeout"/> + </onentry> + + + <transition event="event1" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test205.txml b/test/samples/w3c/txml/test205.txml new file mode 100644 index 0000000..6cc06f4 --- /dev/null +++ b/test/samples/w3c/txml/test205.txml @@ -0,0 +1,34 @@ +<?xml version="1.0"?> +<!-- we test that the processor doesn't change the message. We can't test that it never does this, but +at least we can check that the event name and included data are the same as we sent. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="event1"> + <param name="aParam" conf:expr="1"/> + </send> + <send event="timeout"/> + </onentry> + + + <transition event="event1" target="s1"> + <assign conf:location="1" conf:eventDataFieldValue="aParam"/> + </transition> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s1"> + <transition conf:idVal="1=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test207.txml b/test/samples/w3c/txml/test207.txml new file mode 100644 index 0000000..6893dcf --- /dev/null +++ b/test/samples/w3c/txml/test207.txml @@ -0,0 +1,60 @@ +<?xml version="1.0"?> +<!-- we test that that we can't cancel an event in another session. We invoke a child process. It notifies +us when it has generated a delayed event with sendid foo. We try to cancel foo. The child process sends us event + event success if the event is not cancelled, event fail otherwise. This doesn't test that there is absolutely no way to cancel an event +raised in another session, but the spec doesn't define any way to refer to an event in another process --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="10s"/> + </onentry> + <invoke type="scxml"> + <content> + <!-- when invoked, we raise a delayed event1 with sendid 'foo' and notify our parent. Then we wait. + If event1 occurs, the parent hasn't succeeded in canceling it and we return pass. If event2 occurs + it means event1 was canceled (because event2 is delayed longer than event1) and we return 'fail'. --> + + + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0"> + <onentry> + <send event="event1" id="foo" delay="3s"/> + <send event="event2" delay="5s"/> + <send target="#_parent" event="childToParent"/> + </onentry> + + <transition event="event1" target="subFinal"> + <send target="#_parent" event="pass"/> + </transition> + <transition event="*" target="subFinal"> + <send target="#_parent" event="fail"/> + </transition> + + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <state id="s01"> + <transition event="childToParent" target="s02"> + <cancel sendid="foo"/> + </transition> + </state> + + <state id="s02"> + <transition event="pass" conf:targetpass=""/> + <transition event="fail" conf:targetfail=""/> + <transition event="timeout" conf:targetfail=""/> + </state> + +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test208.txml b/test/samples/w3c/txml/test208.txml new file mode 100644 index 0000000..5a86e6d --- /dev/null +++ b/test/samples/w3c/txml/test208.txml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- we test that cancel works. We cancel delayed event1. If cancel works, we get event2 first and pass. If +we get event1 or an error first, cancel didn't work and we fail. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send id="foo" event="event1" delay="1s"/> + <send event="event2" delay="5s"/> + <cancel sendid="foo"/> + </onentry> + + <transition event="event2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test210.txml b/test/samples/w3c/txml/test210.txml new file mode 100644 index 0000000..402ed36 --- /dev/null +++ b/test/samples/w3c/txml/test210.txml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- we test that sendidexpr works with cancel. If it takes the most recent value of var1, it should cancel +delayed event1. Thus we get event2 first and pass. If we get event1 or an error first, cancel didn't work and we fail. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:quoteExpr="bar"/> + </datamodel> + +<state id="s0"> + <onentry> + <send id="foo" event="event1" delay="1s"/> + <send event="event2" delay="5s"/> + <assign conf:location="1" conf:quoteExpr="foo"/> + <cancel conf:sendIDExpr="1"/> + </onentry> + + <transition event="event2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test215.txml b/test/samples/w3c/txml/test215.txml new file mode 100644 index 0000000..afb8df5 --- /dev/null +++ b/test/samples/w3c/txml/test215.txml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- we test that typexpr is evaluated at runtime. If the original value of var1 is used, the invocation +will fail (test215sub1.scxml is not of type 'foo', even if the platform supports foo as a type). If +the runtime value is used, the invocation will succeed --> + + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<datamodel> + <data conf:id="1" conf:quoteExpr="foo"/> + </datamodel> + +<state id="s0" > + <onentry> + <send event="timeout" delay="5s"/> + <assign conf:location="1" conf:quoteExpr="http://www.w3.org/TR/scxml/"/> + </onentry> + <invoke conf:typeExpr="1"> + <content> + <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. --> + <scxml initial="subFinal" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="done.invoke" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test216.txml b/test/samples/w3c/txml/test216.txml new file mode 100644 index 0000000..e65818e --- /dev/null +++ b/test/samples/w3c/txml/test216.txml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- we test that srcexpr is evaluated at runtime. If the original value of var1 is used, the invocation +will fail (assuming that there is no script named 'foo'). If +the runtime value is used, the invocation will succeed --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<datamodel> + <data conf:id="1" conf:quoteExpr="foo"/> + </datamodel> + +<state id="s0" > + <onentry> + <send event="timeout" delay="5s"/> + <assign conf:location="1" conf:quoteExpr="file:test216sub1.scxml"/> + </onentry> + <invoke conf:srcExpr="1" type="http://www.w3.org/TR/scxml"/> + <transition event="done.invoke" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test220.txml b/test/samples/w3c/txml/test220.txml new file mode 100644 index 0000000..4c79e4d --- /dev/null +++ b/test/samples/w3c/txml/test220.txml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- we test that the scxml type is supported. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s0" > + <onentry> + <send event="timeout" delay="5s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. --> + <scxml initial="subFinal" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"/> + </scxml></content> + </invoke> + <transition event="done.invoke" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test223.txml b/test/samples/w3c/txml/test223.txml new file mode 100644 index 0000000..9cdc499 --- /dev/null +++ b/test/samples/w3c/txml/test223.txml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- we test that idlocation is supported. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1"/> + </datamodel> + +<state id="s0" > + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/" conf:idlocation="1"> + <content> + <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. --> + <scxml initial="subFinal" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="*" target="s1"/> +</state> + +<state id="s1"> + <transition conf:isBound="1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test224.txml b/test/samples/w3c/txml/test224.txml new file mode 100644 index 0000000..0ffe8eb --- /dev/null +++ b/test/samples/w3c/txml/test224.txml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- we test that the automatically generated id has the form stateid.platformid. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1"/> + <data conf:id="2" conf:quoteExpr="s0."/> + </datamodel> + +<state id="s0" > + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/" conf:idlocation="1"> + <content> + <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. --> + <scxml version="1.0" initial="subFinal" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="*" target="s1"/> +</state> + +<state id="s1"> + <transition conf:varPrefix="2 1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test225.txml b/test/samples/w3c/txml/test225.txml new file mode 100644 index 0000000..548ff46 --- /dev/null +++ b/test/samples/w3c/txml/test225.txml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- we test that the automatically generated id is unique, we call invoke twice and compare the ids. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1"/> + <data conf:id="2"/> + </datamodel> + +<state id="s0" > + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" conf:idlocation="1"> + <content> + <scxml initial="subFinal1" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <invoke type="http://www.w3.org/TR/scxml/" conf:idlocation="2" > + <content> + <scxml initial="subFinal2" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + + <transition event="*" target="s1"/> +</state> + +<state id="s1"> + <transition conf:VarEqVar="1 2" conf:targetfail=""/> + <transition conf:targetpass=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test226.txml b/test/samples/w3c/txml/test226.txml new file mode 100644 index 0000000..843bfdc --- /dev/null +++ b/test/samples/w3c/txml/test226.txml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- this is basically just a test that invoke works correctly and that you can pass data +to the invoked process. If the invoked session finds aParam==1, it exits, signalling +success. otherwise it will hang and the timeout in this doc signifies failure. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" > + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + + + <invoke type="http://www.w3.org/TR/scxml/" src="file:test226sub1.txml"> + <param conf:name="1" conf:expr="1"/> + </invoke> + + <transition event="varBound" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test228.txml b/test/samples/w3c/txml/test228.txml new file mode 100644 index 0000000..40021bb --- /dev/null +++ b/test/samples/w3c/txml/test228.txml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- test that the invokeid is included in events returned from the invoked process. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1"/> + </datamodel> + +<state id="s0" > + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" id="foo"> + <content> + <scxml initial="subFinal" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="done.invoke" target="s1"> + <assign conf:location="1" conf:eventField="invokeid"/> + </transition> + <transition event="*" conf:targetfail=""/> +</state> + +<state id="s1"> + <transition conf:idQuoteVal="1=foo" conf:targetpass=""/> + <transition conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test229.txml b/test/samples/w3c/txml/test229.txml new file mode 100644 index 0000000..3837b69 --- /dev/null +++ b/test/samples/w3c/txml/test229.txml @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!-- test that autofoward works. If the child process receives back a copy of the +childToParent event that it sends to this doc, it sends eventReceived, signalling success. (Note +that this doc is not required to process that event explicitly. It should be forwarded in any case.) Otherwise +it eventually times out and the done.invoke signals failure --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" > + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" autoforward="true"> + <content> + <!-- when invoked, send childToParent to parent. + If it is forwarded back to us, send + eventReceived to signal success and terminate. + Otherwise wait for timer to expire and terminate. --> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0"> + <onentry> + <send target="#_parent" event="childToParent"/> + <send event="timeout" delay="3s"/> + </onentry> + <transition event="childToParent" target="subFinal"> + <send target="#_parent" event="eventReceived"/> + </transition> + <transition event="*" target="subFinal"/> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="childToParent"/> + <transition event="eventReceived" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test230.txml b/test/samples/w3c/txml/test230.txml new file mode 100644 index 0000000..fc27220 --- /dev/null +++ b/test/samples/w3c/txml/test230.txml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- a manual test that an autofowarded event has the same fields and values as the original event. +the child process sends the parent process an event which is forwarded back to it. +Both the parent and child process print out the contents of the event. The tester +must check if they are the same and report his result. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/" autoforward="true"> + <content> + <!-- when invoked, send childToParent to parent. If it is forwarded back to us, print out its + fields and terminate. --> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0"> + <onentry> + <send target="#_parent" event="childToParent"/> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="childToParent" target="subFinal"> + <log label="name is " conf:eventField="name" /> + <log label="type is " conf:eventField="type" /> + <log label="sendid is " conf:eventField="sendid"/> + <log label="origin is " conf:eventField="origin" /> + <log label="origintype is " conf:eventField="origintype" /> + <log label="invokeid is " conf:eventField="invokeid" /> + <log label="data is " conf:eventField="data"/> + </transition> + <transition event="*" target="subFinal"/> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="timeout" target="final"/> + + + <state id="s01"> + <transition event="childToParent" target="s02"> + <log label="name is " conf:eventField="name" /> + <log label="type is " conf:eventField="type" /> + <log label="sendid is " conf:eventField="sendid"/> + <log label="origin is " conf:eventField="origin" /> + <log label="origintype is " conf:eventField="origintype" /> + <log label="invokeid is " conf:eventField="invokeid" /> + <log label="data is " conf:eventField="data"/> + </transition> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s02"> + <!-- wait till we get the done event to ensure that the child process has time to print out its results --> + <transition event="done.invoke" target="final"/> + </state> + +</state> + +<final id="final"/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test232.txml b/test/samples/w3c/txml/test232.txml new file mode 100644 index 0000000..1cbc14f --- /dev/null +++ b/test/samples/w3c/txml/test232.txml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<!-- test that a parent process can receive multiple events from a child process --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="subFinal" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"> + <onentry> + <send target="#_parent" event="childToParent1"/> + <send target="#_parent" event="childToParent2"/> + </onentry> + </final> + </scxml> + </content> + </invoke> + <transition event="timeout" conf:targetfail=""/> + + + <state id="s01"> + <transition event="childToParent1" target="s02"/> + </state> + + <state id="s02"> + <transition event="childToParent2" target="s03"/> + </state> + +<state id="s03"> + <transition event="done.invoke" conf:targetpass=""/> + </state> + +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test233.txml b/test/samples/w3c/txml/test233.txml new file mode 100644 index 0000000..94b219b --- /dev/null +++ b/test/samples/w3c/txml/test233.txml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<!-- test that finalize markup runs before the event is processed. The invoked process will +return 2 in _event.data.aParam, so that new value should be in force when we select +the transtitions. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="subFinal" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"> + <onentry> + <send target="#_parent" event="childToParent"> + <param name="aParam" conf:expr="2"/> + </send> + </onentry> + </final> + </scxml> + </content> + <finalize> + <assign conf:location="1" conf:eventDataFieldValue="aParam"/> + </finalize> + </invoke> + + <transition event="childToParent" conf:idVal="1 2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test234.txml b/test/samples/w3c/txml/test234.txml new file mode 100644 index 0000000..27d4626 --- /dev/null +++ b/test/samples/w3c/txml/test234.txml @@ -0,0 +1,70 @@ +<?xml version="1.0"?> +<!-- test that only finalize markup in the invoking state runs. the first invoked process will +return 2 in _event.data.aParam, while second invoked process sleeps without returning any events. +Only the first finalize should execute. So when we get to s1 var1 should have value 2 but +var2 should still be set to 1 --> + + +<scxml initial="p0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + <data conf:id="2" conf:expr="1"/> + </datamodel> +<parallel id="p0"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + + <state id="p01"> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml version="1.0" initial="subFinal1" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal1"> + <onentry> + <send target="#_parent" event="childToParent"> + <param name="aParam" conf:expr="2"/> + </send> + </onentry> + </final> + </scxml> + </content> + <finalize> + <assign conf:location="1" conf:eventDataFieldValue="aParam"/> + </finalize> + </invoke> + + <transition event="childToParent" conf:idVal="1=2" target="s1"/> + <transition event="childToParent" conf:targetfail=""/> + </state> + + <state id="p02"> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml version="1.0" initial="sub0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="subFinal2"/> + </state> + <final id="subFinal2"/> + </scxml> + </content> + <finalize> + <assign conf:location="2" conf:eventDataFieldValue="aParam"/> + </finalize> + </invoke> + </state> + +</parallel> + + +<state id="s1"> + <transition conf:idVal="2=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test235.txml b/test/samples/w3c/txml/test235.txml new file mode 100644 index 0000000..84b8680 --- /dev/null +++ b/test/samples/w3c/txml/test235.txml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- test that done.invoke.id event has the right id. the invoked child terminates immediately +and should generate done.invoke.foo --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/" id="foo"> + <content> + <scxml initial="subFinal" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="done.invoke.foo" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test236.txml b/test/samples/w3c/txml/test236.txml new file mode 100644 index 0000000..5d18c2f --- /dev/null +++ b/test/samples/w3c/txml/test236.txml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<!-- test that done.invoke.id event is the last event we receive. the invoked process sends childToParent +in the exit handler of its final state. We should get it before the done.invoke, and we should get no +events after the done.invoke. Hence timeout indicates success --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="subFinal" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"> + <onexit> + <send target="#_parent" event="childToParent"/> + </onexit> + </final> + </scxml> + </content> + </invoke> + + <transition event="childToParent" target="s1"/> + <transition event="done.invoke" conf:targetfail=""/> +</state> + +<state id="s1"> + <!-- here we should get done.invoke --> + <transition event="done.invoke" target="s2"/> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s2"> + <transition event="timeout" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test237.txml b/test/samples/w3c/txml/test237.txml new file mode 100644 index 0000000..c6097bc --- /dev/null +++ b/test/samples/w3c/txml/test237.txml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<!-- test that cancelling works. invoked child sleeps for two seconds, then terminates. We +sleep for 1 sec in s0, then move to s1. This should cause the invocation to get cancelled. +If we receive done.invoke, the invocation wasn't cancelled, and we fail. If we receive no events by +the time timeout2 fires, success --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="timeout1" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <!-- when invoked, sleep for 2 secs then terminate. Parent will try to cancel this session --> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="subFinal"/> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="timeout1" target="s1"/> + +</state> + +<state id="s1"> + <onentry> + <send event="timeout2" delay="2s"/> + </onentry> + <!-- here we should NOT get done.invoke --> + <transition event="done.invoke" conf:targetfail=""/> + <transition event="*" conf:targetpass=""/> + </state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test239.txml b/test/samples/w3c/txml/test239.txml new file mode 100644 index 0000000..8fa1837 --- /dev/null +++ b/test/samples/w3c/txml/test239.txml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- test that markup can be specified both by 'src' and by <content> --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + + <state id="s01"> + <invoke type="http://www.w3.org/TR/scxml/" src="file:test239sub1.scxml"/> + <transition event="done.invoke" target="s02"/> + </state> + +<state id="s02"> + <invoke type="http://www.w3.org/TR/scxml/"> + <!-- identical to test239sub1.scxml. --> + <content> + <scxml version="1.0" initial="final" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="final"/> + </scxml> + </content> + </invoke> + + <transition event="done.invoke" conf:targetpass=""/> + </state> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test240.txml b/test/samples/w3c/txml/test240.txml new file mode 100644 index 0000000..bf669d4 --- /dev/null +++ b/test/samples/w3c/txml/test240.txml @@ -0,0 +1,71 @@ +<?xml version="1.0"?> +<!-- test that datamodel values can be specified both by 'namelist' and by <param>. +invoked child will return success if its Var1 is set to 1, failure otherwise. This +test will fail schema validation because of the multiple occurences of Var1, but +should run correctly. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + + <state id="s01"> + <invoke type="http://www.w3.org/TR/scxml/" conf:namelist="1"> + <content> + <scxml initial="sub01" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + <state id="sub01"> + <transition conf:namelistIdVal="1=1" target="subFinal1"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal1"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <transition event="success" target="s02"/> + <transition event="failure" conf:targetfail=""/> + </state> + +<state id="s02"> + <invoke type="http://www.w3.org/TR/scxml/"> + <param conf:name="1" conf:expr="1"/> + <content> + <scxml initial="sub02" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + + <state id="sub02"> + <transition conf:idVal="1=1" target="subFinal2"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal1"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + <transition event="success" conf:targetpass=""/> + <transition event="failure" conf:targetfail=""/> + </state> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test241.txml b/test/samples/w3c/txml/test241.txml new file mode 100644 index 0000000..9587697 --- /dev/null +++ b/test/samples/w3c/txml/test241.txml @@ -0,0 +1,102 @@ +<?xml version="1.0"?> +<!-- The child process will return success ifits Var1 is set to 1, failure otherwise. For this test +we try passing in Var1 by param and by namelist and check that we either get two successes +or two failures. This test will fail schema validation due to multiple declarations of +Var1, but should run correctly. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + + <state id="s01"> + <invoke type="http://www.w3.org/TR/scxml/" conf:namelist="1"> + <content> + <scxml initial="sub01" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + + <state id="sub01"> + <transition conf:idVal="1=1" target="subFinal1"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal1"> + <send target="#_parent" event="failure"/> + </transition> + </state> + + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <transition event="success" target="s02"/> + <transition event="failure" target="s03"/> + </state> + +<state id="s02"> + <invoke type="http://www.w3.org/TR/scxml/"> + <param conf:name="1" conf:expr="1"/> + <content> + <scxml initial="sub02" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + + <state id="sub02"> + <transition conf:idVal="1=1" target="subFinal2"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal2"> + <send target="#_parent" event="failure"/> + </transition> + </state> + + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + <!-- we got success in s01, so we need to do so here --> + <transition event="success" conf:targetpass=""/> + <transition event="failure" conf:targetfail=""/> + </state> + +<state id="s03"> + <invoke type="http://www.w3.org/TR/scxml/" > + <param conf:name="1" conf:expr="1"/> + <content> + <scxml initial="sub03" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + + <state id="sub03"> + <transition conf:idVal="1=1" target="subFinal3"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal3"> + <send target="#_parent" event="failure"/> + </transition> + </state> + + <final id="subFinal3"/> + </scxml> + </content> + </invoke> + <!-- we got failure in s01, so we need to do so here --> + <transition event="failure" conf:targetpass=""/> + <transition event="success" conf:targetfail=""/> + </state> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test242.txml b/test/samples/w3c/txml/test242.txml new file mode 100644 index 0000000..35fa154 --- /dev/null +++ b/test/samples/w3c/txml/test242.txml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<!-- test that markup specified by 'src' and by <content> is treated the same way. That means that +either we get done.invoke in both cases or in neither case (in which case we timeout) --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" > + <onentry> + <send event="timeout1" delay="1s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + + <invoke type="http://www.w3.org/TR/scxml/" src="file:test242sub1.scxml"/> + <transition event="done.invoke" target="s02"/> + <transition event="timeout1" target="s03"/> + </state> + +<state id="s02"> + <onentry> + <send event="timeout2" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <!-- identical to test242sub1.scxml. --> + <content> + <scxml version="1.0" initial="subFinal1" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <!-- we got done.invoke last time, so we need it this time too --> + <transition event="done.invoke" conf:targetpass=""/> + <transition event="timeout2" conf:targetfail=""/> + </state> + +<state id="s03"> + <onentry> + <send event="timeout3" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <!-- identical to test242sub1.scxml. --> + <content> + <scxml version="1.0" initial="subFinal2" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + <!-- we got timeout last time, so we need it this time too --> + <transition event="timeout3" conf:targetpass=""/> + <transition event="done.invoke" conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test243.txml b/test/samples/w3c/txml/test243.txml new file mode 100644 index 0000000..a01345c --- /dev/null +++ b/test/samples/w3c/txml/test243.txml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<!-- test that datamodel values can be specified by param. +test240sub1 will return success ifits Var1 is set to 1, failure otherwise. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/"> + <param conf:name="1" conf:expr="1"/> + <content> + <scxml version="1.0" initial="sub0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + + <state id="sub0"> + <transition conf:idVal="1=1" target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="success" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test244.txml b/test/samples/w3c/txml/test244.txml new file mode 100644 index 0000000..c0f1a23 --- /dev/null +++ b/test/samples/w3c/txml/test244.txml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<!-- test that datamodel values can be specified by namelist. +invoked child will return success ifits Var1 is set to 1, failure otherwise. +This test will fail schema validation due to multiple occurrences of Var1, +but should run correctly. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" conf:namelist="1"> + <content> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + + <state id="sub0"> + <transition conf:idVal="1=1" target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="success" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test245.txml b/test/samples/w3c/txml/test245.txml new file mode 100644 index 0000000..459bec6 --- /dev/null +++ b/test/samples/w3c/txml/test245.txml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!-- test that non-existent datamodel values are not set. Var2 is not defined in +invoked child's datamodel. It will will return success if its Var2 remains unbound, failure otherwise. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="2" conf:expr="3"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" conf:namelist="2"> + <content> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0"> + <transition conf:isBound="2" target="subFinal"> + <send target="#_parent" event="failure"/> + </transition> + <transition target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="success" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test247.txml b/test/samples/w3c/txml/test247.txml new file mode 100644 index 0000000..7c528a3 --- /dev/null +++ b/test/samples/w3c/txml/test247.txml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- test that we get done.invoke. timeout indicates failure --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml version="1.0" initial="subFinal" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="done.invoke" conf:targetpass=""/> + <transition event="timeout" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test250.txml b/test/samples/w3c/txml/test250.txml new file mode 100644 index 0000000..3455062 --- /dev/null +++ b/test/samples/w3c/txml/test250.txml @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!-- test that the onexit handlers run in the invoked process if it is cancelled. This has to be a +manual test, since this process won't accept any events from the child process once it has been cancelled. +Tester must examine log output from child process to determine success --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="foo"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" > + <content> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0" initial="sub01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="subFinal"/> + <onexit> + <log conf:quoteExpr="Exiting sub0"/> + </onexit> + <state id="sub01"> + <onexit> + <log conf:quoteExpr="Exiting sub01"/> + </onexit> + </state> + </state> + <final id="subFinal"> + <onentry> + <log conf:quoteExpr="entering final state, invocation was not cancelled"/> + </onentry> + </final> + </scxml> + </content> + </invoke> + + <!-- this transition will cause the invocation to be cancelled --> + <transition event="foo" target="final"/> + </state> + +<final id="final"/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test252.txml b/test/samples/w3c/txml/test252.txml new file mode 100644 index 0000000..40c36cb --- /dev/null +++ b/test/samples/w3c/txml/test252.txml @@ -0,0 +1,51 @@ +<?xml version="1.0"?> +<!-- test that we don't process any events received from the invoked process once it is cancelled. child +process tries to send us childToParent in an onexit handler. If we get it, we fail. +timeout indicates success. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <transition event="timeout" conf:targetpass=""/> + <transition event="childToParent" conf:targetfail=""/> + <transition event="done.invoke" conf:targetfail=""/> + + <state id="s01"> + <onentry> + <send event="foo"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="subFinal"/> + <onexit> + <send target="#_parent" event="childToParent"/> + </onexit> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <!-- this transition will cause the invocation to be cancelled --> + <transition event="foo" target="s02"/> + </state> + + <state id="s02"/> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test253.txml b/test/samples/w3c/txml/test253.txml new file mode 100644 index 0000000..041797a --- /dev/null +++ b/test/samples/w3c/txml/test253.txml @@ -0,0 +1,83 @@ +<?xml version="1.0"?> +<!-- test that the scxml event processor is used in both directions. If child process uses the +scxml event i/o processor to communicate with us, send it an event. It will send back success if +this process uses the scxml processor to send the message to it, otherwise failure. For this test we allow +'scxml' as an alternative to the full url. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1"/> + </datamodel> + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <transition event="timeout" conf:targetfail=""/> + + <invoke type="scxml" id="foo"> + <content> + <!-- inform parent we're running then wait for it to send us an event. If it uses the scxml event i/o + processor to do so, return success, otherwise return failure. --> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="2"/> + </datamodel> + <state id="sub0"> + <onentry> + <send target="#_parent" event="childRunning"/> + </onentry> + + <transition event="parentToChild" target="sub1"> + <assign conf:location="2" conf:eventField="origintype"/> + </transition> + </state> + <state id="sub1"> + <transition conf:idQuoteVal="2=http://www.w3.org/TR/scxml/#SCXMLEventProcessor" target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + <transition conf:idQuoteVal="2=scxml" target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <state id="s01"> + <transition event="childRunning" target="s02"> + <assign conf:location="1" conf:eventField="origintype"/> + </transition> + </state> + + <state id="s02"> + + <transition conf:idQuoteVal="1=http://www.w3.org/TR/scxml/#SCXMLEventProcessor" target="s03"> + <send target="#_foo" event="parentToChild"/> + </transition> + <transition conf:idQuoteVal="1=scxml" target="s03"> + <send target="#_foo" event="parentToChild"/> + </transition> + + <transition conf:targetfail=""/> + + </state> + + + <state id="s03"> + <transition event="success" conf:targetpass=""/> + <transition event="fail" conf:targetfail=""/> + + </state> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test276.txml b/test/samples/w3c/txml/test276.txml new file mode 100644 index 0000000..e4a9d9f --- /dev/null +++ b/test/samples/w3c/txml/test276.txml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> + +<!-- test that values passed in from parent process override default values specified in the child, test276sub1.scxml. +The child returns event1 if var1 has value 1, event0 if it has default value 0. --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s0"> + <invoke type="scxml" src="file:test276sub1.scxml" > + <param conf:name="1" conf:expr="1"/> + </invoke> + <transition event="event1" conf:targetpass=""/> + <transition event="event0" conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test279.txml b/test/samples/w3c/txml/test279.txml new file mode 100644 index 0000000..b3b1adc --- /dev/null +++ b/test/samples/w3c/txml/test279.txml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> + +<!-- testing that in case of early binding variables are assigned values at init time, before + the state containing them is visited --> +<scxml initial="s0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" conf:datamodel="" + xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + + <state id="s0"> + <transition conf:idVal="1=1" conf:targetpass=""/> + + <transition conf:targetfail=""/> + + </state> + +<state id="s1"> + <datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test280.txml b/test/samples/w3c/txml/test280.txml new file mode 100644 index 0000000..723eaa5 --- /dev/null +++ b/test/samples/w3c/txml/test280.txml @@ -0,0 +1,34 @@ +<?xml version="1.0"?> + + +<!-- test late binding. var2 won't get bound until s1 is entered, so it shouldn't have a value in s0 and +accessing it should cause an error. It should get bound before the onentry code in s1 so it should be +possible access it there and assign its value to var1 --> + +<scxml initial="s0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" conf:datamodel="" + binding="late" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <datamodel> + <data conf:id="1"/> + </datamodel> + + <state id="s0"> + <transition conf:unboundVar="2" target="s1"/> + <transition conf:targetfail=""/> + </state> + +<state id="s1"> + <datamodel> + <data conf:id="2" conf:expr="1"/> + </datamodel> + <onentry> + <assign conf:location="1" conf:varExpr="2"/> + </onentry> + <transition conf:VarEqVar="1 2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test286.txml b/test/samples/w3c/txml/test286.txml new file mode 100644 index 0000000..89b77a9 --- /dev/null +++ b/test/samples/w3c/txml/test286.txml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> + +<!-- test that assigment to a non-declared var causes an error. the transition on foo catches the case +where no error is raised --> + +<scxml xmlns="http://www.w3.org/2005/07/scxml" + xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" conf:datamodel="" initial="s0"> + + + <state id="s0"> + <onentry> + <assign conf:location="1" conf:expr="1"/> + <raise event="foo"/> + </onentry> + + <transition event="error.execution" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml> diff --git a/test/samples/w3c/txml/test287.txml b/test/samples/w3c/txml/test287.txml new file mode 100644 index 0000000..8f25165 --- /dev/null +++ b/test/samples/w3c/txml/test287.txml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- a simple test that a legal value may be assigned to a valid data model location --> + +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" + conf:datamodel="" version="1.0" initial="s0"> + +<datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + + <state id="s0"> + <onentry> + <assign conf:location="1" conf:expr="1"/> + </onentry> + + <transition conf:idVal="1=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test294.txml b/test/samples/w3c/txml/test294.txml new file mode 100644 index 0000000..507ff3b --- /dev/null +++ b/test/samples/w3c/txml/test294.txml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<!-- test that a param inside donedata ends up in the data field of the done event and +that content inside donedata sets the full value of the event.data field --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" conf:datamodel="" initial="s0"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + + <state id="s0" initial="s01"> + + <transition event="done.state.s0" conf:eventvarVal="1=1" target="s1"> + </transition> + + <transition event="done.state.s0" conf:targetfail=""> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <param conf:name="1" conf:expr="1"/> + </donedata> + </final> + </state> + + <state id="s1" initial="s11"> + + <transition event="done.state.s1" conf:eventdataVal="foo" conf:targetpass=""> + </transition> + + <transition event="done.state.s1" conf:targetfail=""> + </transition> + + <state id="s11"> + <transition target="s12"/> + </state> + <final id="s12"> + <donedata> + <conf:contentFoo/> + </donedata> + </final> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test298.txml b/test/samples/w3c/txml/test298.txml new file mode 100644 index 0000000..e1af350 --- /dev/null +++ b/test/samples/w3c/txml/test298.txml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- refence a non-existent data model location in param in donedata and see that the right error is raised --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" conf:datamodel="" initial="s0"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + + <state id="s0" initial="s01"> + <transition event="error.execution" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <param conf:name="3" conf:location="2"/> + </donedata> + </final> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml> + + diff --git a/test/samples/w3c/txml/test301.txml b/test/samples/w3c/txml/test301.txml new file mode 100644 index 0000000..d3245f3 --- /dev/null +++ b/test/samples/w3c/txml/test301.txml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- the processor should reject this document because it can't download the script. +Therefore we fail if it runs at all. This test is valid only for datamodels that support scripting --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> + <script conf:scriptBadSrc=""/> + + <state id="s0"> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test302.txml b/test/samples/w3c/txml/test302.txml new file mode 100644 index 0000000..f1b99c0 --- /dev/null +++ b/test/samples/w3c/txml/test302.txml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- test that a script is evaluated at load time. <conf:script> shoudl assign the value 1 to +Var1. Hence, if script is evaluated at download time, Var1 has a value in the initial state s0. +This test is valid only for datamodels that support scripting --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" + xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> + <conf:script/> + + <state id="s0"> + <transition conf:idVal="1=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test303.txml b/test/samples/w3c/txml/test303.txml new file mode 100644 index 0000000..6fd1e9c --- /dev/null +++ b/test/samples/w3c/txml/test303.txml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- to test that scripts are run as part of executable content, we check that it changes the value of a var at the +right point. This test is valid only for datamodels that support scripting --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> +<datamodel> +<data conf:id="1" conf:expr="0"/> +</datamodel> + + <state id="s0"> + <onentry> + <assign conf:location="1" conf:expr="2"/> + <conf:script/> + </onentry> + <transition conf:idVal="1=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test304.txml b/test/samples/w3c/txml/test304.txml new file mode 100644 index 0000000..9ed6cbb --- /dev/null +++ b/test/samples/w3c/txml/test304.txml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- test that a variable declared by a script can be accessed like any other part of the data model --> + +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> + <conf:script/> + + <state id="s0"> + <transition conf:idVal="1=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test307.txml b/test/samples/w3c/txml/test307.txml new file mode 100644 index 0000000..4065f5f --- /dev/null +++ b/test/samples/w3c/txml/test307.txml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?><scxml xmlns="http://www.w3.org/2005/07/scxml" +xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" binding="late"> + +<!-- with binding=late, in s0 we access a variable that isn't created until we get to s1. Then in s1 +we access a non-existent substructure of a variable. We use log tags to report the values that both operations +yield, and whether there are errors. This is a manual test, since the tester must report whether the output +is the same in the two cases --> + +<state id="s0"> + <onentry> + <log label="entering s0 value of Var 1 is: " conf:varExpr="1"/> + <raise event="foo"/> + </onentry> + <transition event="error" target="s1"> + <log label="error in state s0" conf:expr="_event"/> + </transition> + <transition event="foo" target="s1"> + <log label="no error in s0" conf:expr=""/> + </transition> + </state> + +<state id="s1"> + <datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + + <onentry> + <log label="entering s1, value of non-existent substructure of Var 1 is: " conf:varNonexistentStruct="1"/> + <raise event="bar"/> + </onentry> + + <transition event="error" target="final"> + <log label="error in state s1" conf:expr="_event"/> + </transition> + <transition event="bar" target="final"> + <log label="No error in s1" conf:expr=""/> + </transition> + +</state> + +<final id="final"/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test309.txml b/test/samples/w3c/txml/test309.txml new file mode 100644 index 0000000..c781100 --- /dev/null +++ b/test/samples/w3c/txml/test309.txml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- test that an expression that cannot be interpreted as a boolean is treated as false --> + +<scxml version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> + +<state id="s0"> + <transition conf:nonBoolean="" conf:targetfail=""/> + <transition conf:targetpass=""/> + </state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test310.txml b/test/samples/w3c/txml/test310.txml new file mode 100644 index 0000000..f88a87a --- /dev/null +++ b/test/samples/w3c/txml/test310.txml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- simple test of the in() predicate --> + +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" conf:datamodel="" +xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="p"> + + + <parallel id="p"> + + <state id="s0"> + <transition conf:inState="s1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <state id="s1"/> + </parallel> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test311.txml b/test/samples/w3c/txml/test311.txml new file mode 100644 index 0000000..f6485be --- /dev/null +++ b/test/samples/w3c/txml/test311.txml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- test that assignment to a non-existent location yields an error --> + +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" conf:datamodel="" +xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> + + +<state id="s0"> + <onentry> + <assign conf:location="1" conf:expr="1"/> + </onentry> + <transition event="error.execution" conf:targetpass=""/> + <transition event=".*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test312.txml b/test/samples/w3c/txml/test312.txml new file mode 100644 index 0000000..597200b --- /dev/null +++ b/test/samples/w3c/txml/test312.txml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- test that assignment with an illegal expr raises an error --> + +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" conf:datamodel="" +xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> + +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign conf:location="1" conf:illegalExpr=""/> + <raise event="foo"/> + </onentry> + <transition event="error.execution" conf:targetpass=""/> + <transition event=".*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test313.txml b/test/samples/w3c/txml/test313.txml new file mode 100644 index 0000000..ee11064 --- /dev/null +++ b/test/samples/w3c/txml/test313.txml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- this is a manual test. The processor is allowed to reject this doc, but if it executes it with its illegal +expression, it must raise an error --> + +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" conf:datamodel="" +xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> + +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign conf:location="1" conf:illegalExpr=""/> + <raise event="foo"/> + </onentry> + <transition event="error.execution" conf:targetpass=""/> + <transition event=".*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test314.txml b/test/samples/w3c/txml/test314.txml new file mode 100644 index 0000000..7a2329e --- /dev/null +++ b/test/samples/w3c/txml/test314.txml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- this is a manual test because the processor is allowed to reject this document. But if it executes it, +it should not raise an error until it gets to s03 and evaluates the illegal expr --> + +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" + conf:datamodel="" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + + +<state id="s0" initial="s01"> + <transition event="error.execution" conf:targetfail=""/> + + <state id="s01"> + <transition target="s02"/> + </state> + + <state id="s02"> + <transition target="s03"/> + </state> + + <state id="s03"> + <onentry> + <assign conf:location="1" conf:illegalExpr=""/> + <raise event="foo"/> + </onentry> + <transition event="error.execution" conf:targetpass=""/> + <transition event=".*" conf:targetfail=""/> + </state> + +</state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test318.txml b/test/samples/w3c/txml/test318.txml new file mode 100644 index 0000000..9e71bc6 --- /dev/null +++ b/test/samples/w3c/txml/test318.txml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> + +<!-- test that _event stays bound during the onexit and entry into the next state --> + +<scxml initial="s0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" conf:datamodel="" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1"/> + </datamodel> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" target="s1"/> + </state> + + <state id="s1"> + <onentry> + <raise event="bar"/> + <!-- _event should still be bound to 'foo' at this point --> + <assign conf:location="1" conf:eventName=""/> + </onentry> + <transition conf:idQuoteVal="1=foo" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test319.txml b/test/samples/w3c/txml/test319.txml new file mode 100644 index 0000000..50e4a97 --- /dev/null +++ b/test/samples/w3c/txml/test319.txml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> + +<!-- test that _event is not bound before any event has been raised --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" + name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s0"> + <onentry> + <if conf:systemVarIsBound="_event"> + <raise event="bound"/> + <else/> + <raise event="unbound"/> + </if> + </onentry> + <transition event="unbound" conf:targetpass=""/> + <transition event="bound" conf:targetfail=""/> + + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test321.txml b/test/samples/w3c/txml/test321.txml new file mode 100644 index 0000000..74da9c3 --- /dev/null +++ b/test/samples/w3c/txml/test321.txml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> + +<!-- test that _sessionid is bound on startup --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="$_sessionid"/> + </datamodel> + + <state id="s0"> +<transition conf:isBound="1" conf:targetpass=""/> + <transition conf:true="" conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test322.txml b/test/samples/w3c/txml/test322.txml new file mode 100644 index 0000000..6900eef --- /dev/null +++ b/test/samples/w3c/txml/test322.txml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> + +<!-- test that _sessionid remains bound to the same value throught the session. this means that it can't +be assigned to --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:systemVarExpr="_sessionid"/> + <data conf:id="2"/> + </datamodel> + + <state id="s0"> + <transition target="s1"/> + + </state> + + <state id="s1"> + <onentry> + <assign conf:systemVarLocation="_sessionid" conf:quoteExpr="otherName"/> + <raise event="foo"/> + </onentry> + + <transition event="error.execution" target="s2"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s2"> + + <transition conf:idSystemVarVal="1=_sessionid" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test323.txml b/test/samples/w3c/txml/test323.txml new file mode 100644 index 0000000..afd3400 --- /dev/null +++ b/test/samples/w3c/txml/test323.txml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> + +<!-- test that _name is bound on startup --> + +<scxml initial="s0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" conf:datamodel="" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="$_name"/> + </datamodel> + + <state id="s0"> +<transition conf:isBound="1" conf:targetpass=""/> + <transition conf:true="" conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test324.txml b/test/samples/w3c/txml/test324.txml new file mode 100644 index 0000000..d1b304d --- /dev/null +++ b/test/samples/w3c/txml/test324.txml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> + +<!-- test that _name stays bound till the session ends. This means that it cannot be assigned to --> + +<scxml initial="s0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" conf:datamodel="" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + + <state id="s0"> + <transition conf:nameVarVal="machineName" target="s1"/> + <transition conf:targetfail=""/> + </state> + + <state id="s1"> + <onentry> + <assign conf:systemVarLocation="_name" expr="'otherName'"/> + </onentry> + <transition conf:nameVarVal="machineName" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test325.txml b/test/samples/w3c/txml/test325.txml new file mode 100644 index 0000000..53623c3 --- /dev/null +++ b/test/samples/w3c/txml/test325.txml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> + +<!-- test that _ioprocessors is bound at startup. I'm not sure how to test for a set value or +how to test that the entries in it do represent I/O processors, since the set that each implementation +supports may be different. Suggestions welcome --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:systemVarExpr="_ioprocessors"/> + </datamodel> + + + <state id="s0"> + <transition conf:isBound="1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test326.txml b/test/samples/w3c/txml/test326.txml new file mode 100644 index 0000000..008e786 --- /dev/null +++ b/test/samples/w3c/txml/test326.txml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> + +<!-- test that _ioprocessors stays bound till the session ends. This means that it cannot be assigned to --> +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:systemVarExpr="_ioprocessors"/> + <data conf:id="2"/> + </datamodel> + + <state id="s0"> + <transition conf:isBound="1" target="s1"/> + <transition conf:true="" conf:targetfail=""/> + </state> + + + <state id="s1"> + <onentry> + <assign conf:systemVarLocation="_ioprocessors" conf:quoteExpr="otherName"/> + <raise event="foo"/> + </onentry> + + <transition event="error.execution" target="s2"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s2"> + <onentry> + <assign conf:location="2" conf:systemVarExpr="_ioprocessors"/> + </onentry> + <transition conf:VarEqVarStruct="1 2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test329.txml b/test/samples/w3c/txml/test329.txml new file mode 100644 index 0000000..2552e1f --- /dev/null +++ b/test/samples/w3c/txml/test329.txml @@ -0,0 +1,55 @@ +<!-- test that none of the system variables can be modified --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1"/> + <data conf:id="2"/> + <data conf:id="3"/> + <data conf:id="4"/> + </datamodel> + + <state id="s0"> + <onentry> + <!-- get _event bound so we can use it in s1--> + <raise event="foo"/> + <assign conf:location="1" conf:systemVarExpr="_sessionid"/> + <assign conf:systemVarLocation="_sessionid" conf:invalidSessionID=""/> + </onentry> + + <transition event="foo" conf:idSystemVarVal="1=_sessionid" target="s1"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s1"> + <onentry> + <assign conf:location="2" conf:systemVarExpr="_event"/> + <assign conf:systemVarLocation="_event" expr="27"/> + </onentry> + <transition conf:idSystemVarVal="2=_event" target="s2"/> + <transition conf:targetfail=""/> + </state> + +<state id="s2"> + <onentry> + <assign conf:location="3" conf:systemVarExpr="_name"/> + <assign conf:systemVarLocation="_name" expr="27"/> + </onentry> + <transition conf:idSystemVarVal="3=_name" target="s3"/> + <transition conf:targetfail=""/> + </state> + + +<state id="s3"> + <onentry> + <assign conf:location="4" conf:systemVarExpr="_ioprocessors"/> + <assign conf:systemVarLocation="_ioprocessors" expr="27"/> + </onentry> + <transition conf:idSystemVarVal="4=_ioprocessors" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test330.txml b/test/samples/w3c/txml/test330.txml new file mode 100644 index 0000000..7778fad --- /dev/null +++ b/test/samples/w3c/txml/test330.txml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> + +<!-- check that the required fields are present in both internal and external events --> + +<scxml initial="s0" conf:datamodel="" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" conf:eventFieldsAreBound="" target="s1"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s1"> + <onentry> + <send event="foo"/> + </onentry> + <transition event="foo" conf:eventFieldsAreBound="" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test331.txml b/test/samples/w3c/txml/test331.txml new file mode 100644 index 0000000..a273b14 --- /dev/null +++ b/test/samples/w3c/txml/test331.txml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<scxml version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" name="machineName"> + +<!-- test that _event.type is set correctly for internal, platform, and external events --> +<datamodel> + <data conf:id="1"/> + </datamodel> + + <state id="s0"> + <onentry> + <!-- internal event --> + <raise event="foo"/> + </onentry> + <transition event="foo" target="s1"> + <assign conf:location="1" conf:eventType=""/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> + <transition conf:idQuoteVal="1=internal" target="s2"/> + <transition conf:targetfail=""/> + </state> + +<state id="s2"> + <onentry> + <!-- this will generate an error, which is a platform event --> + <assign conf:location="2" conf:expr="1"/> + </onentry> + <transition event="error" target="s3"> + <assign conf:location="1" conf:eventType=""/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s3"> + <transition conf:idQuoteVal="1=platform" target="s4"/> + <transition conf:targetfail=""/> + </state> + + <state id="s4"> + <onentry> + <!-- external event --> + <send event="foo"/> + </onentry> + <transition event="foo" target="s5"> + <assign conf:location="1" conf:eventType=""/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s5"> + <transition conf:idQuoteVal="1=external" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + + <final xmlns="http://www.w3.org/2005/07/scxml" id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final xmlns="http://www.w3.org/2005/07/scxml" id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test332.txml b/test/samples/w3c/txml/test332.txml new file mode 100644 index 0000000..0f87545 --- /dev/null +++ b/test/samples/w3c/txml/test332.txml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> + +<!-- test that sendid is present in error events triggered by send errors --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" initial="s0" conf:datamodel="" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1"/> + <data conf:id="2"/> + </datamodel> + + + <state id="s0"> + <onentry> + <!-- this will raise an error and also store the sendid in var1 --> + <send conf:illegalTarget="" event="foo" conf:idlocation="1"/> + </onentry> + <transition event="error" target="s1"> + <!-- get the sendid out of the error event --> + <assign conf:location="2" conf:eventSendid=""/> + </transition> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s1"> +<!-- make sure that the sendid in the error event matches the one generated when send executed --> + <transition conf:VarEqVar="1 2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test333.txml b/test/samples/w3c/txml/test333.txml new file mode 100644 index 0000000..38a5097 --- /dev/null +++ b/test/samples/w3c/txml/test333.txml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> + +<!-- make sure sendid is blank in a non-error event --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" initial="s0" conf:datamodel="" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s0"> + <onentry> + <send event="foo"/> + </onentry> + <transition event="foo" conf:eventFieldHasNoValue="sendid" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test335.txml b/test/samples/w3c/txml/test335.txml new file mode 100644 index 0000000..e9c70b2 --- /dev/null +++ b/test/samples/w3c/txml/test335.txml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> + +<!-- test that origin field is blank for internal events --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" initial="s0" conf:datamodel="" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" conf:eventFieldHasNoValue="origin" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test336.txml b/test/samples/w3c/txml/test336.txml new file mode 100644 index 0000000..889cb94 --- /dev/null +++ b/test/samples/w3c/txml/test336.txml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> + +<!-- test that the origin field of an external event contains a URL that lets you send back to the originator. In +this case it's the same session, so if we get bar we succeed --> + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s0"> + <onentry> + <send event="foo"/> + </onentry> + <transition event="foo" target="s1"> + <conf:sendToSender name="bar"/> + </transition> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s1"> + <onentry> + <send event="baz"/> + </onentry> + <transition event="bar" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test337.txml b/test/samples/w3c/txml/test337.txml new file mode 100644 index 0000000..4d5e44f --- /dev/null +++ b/test/samples/w3c/txml/test337.txml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> + +<!-- test that origintype is blank on internal events --> + +<scxml initial="s0" conf:datamodel="" version="1.0" name="machineName" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" conf:eventFieldHasNoValue="origintype" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test338.txml b/test/samples/w3c/txml/test338.txml new file mode 100644 index 0000000..5f81086 --- /dev/null +++ b/test/samples/w3c/txml/test338.txml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> + +<!-- test that invokeid is set correctly in events received from an invoked process. timeout event catches the +case where the invoke doesn't work correctly --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1"/> + <data conf:id="2"/> + </datamodel> + + <state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <invoke conf:idlocation="1" type="http://www.w3.org/TR/scxml/" > + <content> + <scxml initial="sub0" version="1.0" conf:datamodel="" name="machineName"> + <final id="sub0"> + <onentry> + <send target="#_parent" event="event1"/> + </onentry> + </final> + </scxml> + </content> + </invoke> + <transition event="event1" target="s1"> + <assign conf:location="2" conf:eventField="invokeid"/> + </transition> + <transition event="event0" conf:targetfail=""/> + </state> + +<state id="s1"> + <transition conf:VarEqVar="1 2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test339.txml b/test/samples/w3c/txml/test339.txml new file mode 100644 index 0000000..7ea1081 --- /dev/null +++ b/test/samples/w3c/txml/test339.txml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> + +<!-- test that invokeid is blank in an event that wasn't returned from an invoked process --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" conf:eventFieldHasNoValue="invokeid" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test342.txml b/test/samples/w3c/txml/test342.txml new file mode 100644 index 0000000..d8f330a --- /dev/null +++ b/test/samples/w3c/txml/test342.txml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> + +<!-- test that eventexpr works and sets the name field of the resulting event --> +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:quoteExpr="foo"/> + <data conf:id="2"/> + </datamodel> + + <state id="s0"> + <onentry> + <send conf:eventExpr="1"/> + </onentry> + <transition event="foo" target="s1"> + <assign conf:location="2" conf:eventField="name"/> + </transition> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s1"> + <transition conf:VarEqVar="1 2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test343.txml b/test/samples/w3c/txml/test343.txml new file mode 100644 index 0000000..1d13da6 --- /dev/null +++ b/test/samples/w3c/txml/test343.txml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- test that illegal <param> produces error.execution and empty event.data --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" conf:datamodel="" initial="s0"> + + + <state id="s0" initial="s01"> + <!-- we should get the error before the done event --> + <transition event="error.execution" target="s1"/> + <transition event="done.state.s0" conf:targetfail=""/> + + <transition event="done.state.s0" conf:targetfail=""> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <param conf:location="foo" name="someParam"/> + </donedata> + </final> + </state> + + + <!-- if we get here, we received the error event. Now check that the done + event has empty event.data --> + + <state id="s1"> + <transition event="done.state.s0" conf:emptyEventData="" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test344.txml b/test/samples/w3c/txml/test344.txml new file mode 100644 index 0000000..8bf6270 --- /dev/null +++ b/test/samples/w3c/txml/test344.txml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- test that a non-boolean cond expression evaluates to false and causes error.execution to be raised --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" + conf:datamodel="" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0"> + +<state id="s0"> + <transition conf:nonBoolean="" conf:targetfail=""/> + <transition target="s1"/> + </state> + +<state id="s1"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="error.execution" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test346.txml b/test/samples/w3c/txml/test346.txml new file mode 100644 index 0000000..10db614 --- /dev/null +++ b/test/samples/w3c/txml/test346.txml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> + +<!-- test that any attempt to change the value of a system variable causes error.execution to be raised. +Event1..4 are there to catch the case where the error event is not raised. In cases where it is, we have +to dispose of eventn in the next state, hence the targetless transitions (which simply throw away the event.) --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" name="machineName" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + + <state id="s0"> + <onentry> + <assign conf:systemVarLocation="_sessionid" conf:quoteExpr="otherName"/> + <raise event="event1"/> + </onentry> + + <transition event="error.execution" target="s1"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s1"> + <onentry> + <assign conf:systemVarLocation="_event" conf:quoteExpr="otherName"/> + <raise event="event2"/> + </onentry> + <!-- throw out event1 if it's still around --> + <transition event="event1"/> + <transition event="error.execution" target="s2"/> + <!-- event1 would trigger this transition if we didn't drop it. We want this transition to have + a very general trigger to catch cases where the wrong error event was raised --> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s2"> + <onentry> + <assign conf:systemVarLocation="_ioprocessors" conf:quoteExpr="otherName"/> + <raise event="event3"/> + </onentry> + <transition event="event2"/> + <transition event="error.execution" target="s3"/> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s3"> + <onentry> + <assign conf:systemVarLocation="_name" conf:quoteExpr="otherName"/> + <raise event="event4"/> + </onentry> + <transition event="event3"/> + <transition event="error.execution" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test355.txml b/test/samples/w3c/txml/test355.txml new file mode 100644 index 0000000..4136801 --- /dev/null +++ b/test/samples/w3c/txml/test355.txml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- test that default initial state is first in document order. If we enter s0 first we succeed, if s1, failure. --> + + +<scxml conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <transition conf:targetpass=""/> +</state> + +<state id="s1"> + <transition conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test364.txml b/test/samples/w3c/txml/test364.txml new file mode 100644 index 0000000..a302f54 --- /dev/null +++ b/test/samples/w3c/txml/test364.txml @@ -0,0 +1,77 @@ +<?xml version="1.0"?> +<!-- test that default initial states are entered when a compound state is entered. First we test +the 'initial' attribute, then the initial element, then default to the first child in document order. +If we get to s01111 we succeed, if any other state, failure. --> + + +<scxml conf:datamodel="" initial="s1" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s1" initial="s11p112 s11p122"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + <state id="s11" initial="s111"> + <state id="s111"/> + <parallel id="s11p1"> + <state id="s11p11" initial="s11p111"> + <state id="s11p111"/> + <state id="s11p112"> + <onentry> + <raise event="In-s11p112"/> + </onentry> + </state> + </state> + <state id="s11p12" initial="s11p121"> + <state id="s11p121"/> + <state id="s11p122"> + <transition event="In-s11p112" target="s2"/> + </state> + </state> + </parallel> + </state> +</state> + +<state id="s2"> + <initial> + <transition target="s21p112 s21p122"/> + </initial> + <transition event="timeout" conf:targetfail=""/> + <state id="s21" initial="s211"> + <state id="s211"/> + <parallel id="s21p1"> + <state id="s21p11" initial="s21p111"> + <state id="s21p111"/> + <state id="s21p112"> + <onentry> + <raise event="In-s21p112"/> + </onentry> + </state> + </state> + <state id="s21p12" initial="s21p121"> + <state id="s21p121"/> + <state id="s21p122"> + <transition event="In-s21p112" target="s3"/> + </state> + </state> + </parallel> + </state> +</state> + +<state id="s3"> + <transition conf:targetfail=""/> + <state id="s31"> + <state id="s311"> + <state id="s3111"> + <transition conf:targetpass=""/> + </state> + <state id="s3112"/> + <state id="s312"/> + <state id="s32"/> +</state> +</state> +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test372.txml b/test/samples/w3c/txml/test372.txml new file mode 100644 index 0000000..84cb8f6 --- /dev/null +++ b/test/samples/w3c/txml/test372.txml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- test that entering a final state generates done.state.parentid after executing the onentry elements. +Var1 should be set to 2 (but not 3) by the time the event is raised --> + + +<scxml conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + +<state id="s0" initial="s0final"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="done.state.s0" conf:idVal="1=2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + + <final id="s0final"> + <onentry> + <assign conf:location="1" conf:expr="2"/> + </onentry> + <onexit> + <assign conf:location="1" conf:expr="3"/> + </onexit> + </final> +</state> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test375.txml b/test/samples/w3c/txml/test375.txml new file mode 100644 index 0000000..47d42c5 --- /dev/null +++ b/test/samples/w3c/txml/test375.txml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- test that onentry handlers are executed in document order. event1 should be raised before event2 --> + + +<scxml conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + + +<state id="s0"> + <onentry> + <raise event="event1"/> + </onentry> + <onentry> + <raise event="event2"/> + </onentry> + + <transition event="event1" target="s1"/> + <transition event="*" conf:targetfail=""/> + +</state> + +<state id="s1"> + <transition event="event2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test376.txml b/test/samples/w3c/txml/test376.txml new file mode 100644 index 0000000..86c2c2c --- /dev/null +++ b/test/samples/w3c/txml/test376.txml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- test that each onentry handler is a separate block. The <send> of event1 will cause an error but + the increment to var1 should happen anyways --> + + +<scxml conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send conf:illegalTarget="" event="event1"/> + </onentry> + <onentry> + <conf:incrementID id="1"/> + </onentry> + + <transition conf:idVal="1=2" conf:targetpass=""/> + <transition conf:targetfail=""/> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test377.txml b/test/samples/w3c/txml/test377.txml new file mode 100644 index 0000000..bca44ca --- /dev/null +++ b/test/samples/w3c/txml/test377.txml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- test that onexit handlers are executed in document order. event1 should be raised before event2 --> + + +<scxml conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + + +<state id="s0"> + <onexit> + <raise event="event1"/> + </onexit> + <onexit> + <raise event="event2"/> + </onexit> + + <transition target="s1"/> + </state> + + <state id="s1"> + + <transition event="event1" target="s2"/> + <transition event="*" conf:targetfail=""/> + +</state> + +<state id="s2"> + <transition event="event2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> +</state> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test378.txml b/test/samples/w3c/txml/test378.txml new file mode 100644 index 0000000..0e553c4 --- /dev/null +++ b/test/samples/w3c/txml/test378.txml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- test that each onexithandler is a separate block. The <send> of event1 will cause an error but + the increment to var1 should happen anyways --> + + +<scxml version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + +<state id="s0"> + <onexit> + <send conf:illegalTarget="" event="event1"/> + </onexit> + <onexit> + <conf:incrementID id="1"/> + </onexit> + +<transition target="s1"/> +</state> + +<state id="s1"> + <transition conf:idVal="1=2" conf:targetpass=""/> + <transition conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test387.txml b/test/samples/w3c/txml/test387.txml new file mode 100644 index 0000000..8997580 --- /dev/null +++ b/test/samples/w3c/txml/test387.txml @@ -0,0 +1,101 @@ +<?xml version="1.0"?> +<!-- test that the default history state works correctly. From initial state s3 we take a transition to s0's default +shallow history state. That should generate "enteringS011", which takes us to s4. In s4, we +transition to s1's default deep history state. We should end up in s122, generating "enteringS122". Otherwise failure.--> + + +<scxml initial="s3" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + + <transition event="enteringS011" target="s4"/> + <transition event="*" conf:targetfail=""/> + + <history type="shallow" id="s0HistShallow"> + <transition target="s01"/> + </history> + <history type="deep" id="s0HistDeep"> + <transition target="s022"/> + </history> + <state id="s01" initial="s011"> + <state id="s011"> + <onentry> + <raise event="enteringS011"/> + </onentry> + </state> + <state id="s012"> + <onentry> + <raise event="enteringS012"/> + </onentry> + </state> + </state> + <state id="s02" initial="s021"> + <state id="s021"> + <onentry> + <raise event="enteringS021"/> + </onentry> + </state> + <state id="s022"> + <onentry> + <raise event="enteringS022"/> + </onentry> + </state> + </state> + +</state> + +<state id="s1" initial="s11"> + + <transition event="enteringS122" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + + <history type="shallow" id="s1HistShallow"> + <transition target="s11"/> + </history> + <history type="deep" id="s1HistDeep"> + <transition target="s122"/> + </history> + <state id="s11" initial="s111"> + <state id="s111"> + <onentry> + <raise event="enteringS111"/> + </onentry> + </state> + <state id="s112"> + <onentry> + <raise event="enteringS112"/> + </onentry> + </state> + </state> + <state id="s12" initial="s121"> + <state id="s121"> + <onentry> + <raise event="enteringS121"/> + </onentry> + </state> + <state id="s122"> + <onentry> + <raise event="enteringS122"/> + </onentry> + </state> + </state> + +</state> + + +<state id="s3"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition target="s0HistShallow"/> +</state> + +<state id="s4"> + <transition target="s1HistDeep"/> +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test388.txml b/test/samples/w3c/txml/test388.txml new file mode 100644 index 0000000..36d58cc --- /dev/null +++ b/test/samples/w3c/txml/test388.txml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<!-- test that history states works correctly. The counter Var1 counts how many times +we have entered s0. The initial state is s012. We then transition to s1, which transitions +to s0's deep history state. entering.s012 should be raised, otherwise failure. Then we transition +to s02, which transitions to s0's shallow history state. That should have value s01, and its initial +state is s011, so we should get entering.s011, otherwise failure.--> + + +<scxml version="1.0" initial="s012" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + +<state id="s0" initial="s01"> + <onentry> + <conf:incrementID id="1"/> + </onentry> + + <!-- the first time through, go to s1, setting a timer just in case something hangs --> + <transition event="entering.s012" conf:idVal="1=1" target="s1"> + <send event="timeout" delay="2s"/> + </transition> + + <!-- the second time, we should get entering.s012. If so, go to s2, otherwise fail --> + <transition event="entering.s012" conf:idVal="1=2" target="s2"/> + <transition event="entering" conf:idVal="1=2" conf:targetfail=""/> + + <!-- the third time we should get entering-s011. If so, pass, otherwise fail --> + <transition event="entering.s011" conf:idVal="1=3" conf:targetpass=""/> + <transition event="entering" conf:idVal="1=3" conf:targetfail=""/> + + <!-- if we timeout, the state machine is hung somewhere, so fail --> + <transition event="timeout" conf:targetfail=""/> + + <history type="shallow" id="s0HistShallow"> + <transition target="s02"/> + </history> + <history type="deep" id="s0HistDeep"> + <transition target="s022"/> + </history> + <state id="s01" initial="s011"> + <state id="s011"> + <onentry> + <raise event="entering.s011"/> + </onentry> + </state> + <state id="s012"> + <onentry> + <raise event="entering.s012"/> + </onentry> + </state> + </state> + <state id="s02" initial="s021"> + <state id="s021"> + <onentry> + <raise event="entering.s021"/> + </onentry> + </state> + <state id="s022"> + <onentry> + <raise event="entering.s022"/> + </onentry> + </state> + </state> + +</state> + + +<state id="s1"> + <transition target="s0HistDeep"/> +</state> + +<state id="s2"> + <transition target="s0HistShallow"/> +</state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test396.txml b/test/samples/w3c/txml/test396.txml new file mode 100644 index 0000000..3af03c9 --- /dev/null +++ b/test/samples/w3c/txml/test396.txml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- test that the value in _event.name matches the event name used to match against transitions --> + + +<scxml conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + + + <transition event="foo" conf:eventNameVal="foo" conf:targetpass=""/> + <transition event="foo" conf:targetfail=""/> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test399.txml b/test/samples/w3c/txml/test399.txml new file mode 100644 index 0000000..9eeced2 --- /dev/null +++ b/test/samples/w3c/txml/test399.txml @@ -0,0 +1,70 @@ +<?xml version="1.0"?> +<!-- test that the event name matching works correctly, including prefix matching and the fact +that the event attribute of transition may contain multiple event designators. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <!-- this will catch the failure case --> + <transition event="timeout" conf:targetfail=""/> + + <state id="s01"> + <onentry> + <raise event="foo"/> + </onentry> + <!-- test that an event can match against a transition with multiple descriptors --> + <transition event="foo bar" target="s02"/> + </state> + + <state id="s02"> + <onentry> + <raise event="bar"/> + </onentry> + <!-- test that an event can match the second descriptor as well --> + <transition event="foo bar" target="s03"/> + </state> + + <state id="s03"> + <onentry> + <raise event="foo.zoo"/> + </onentry> + <!-- test that a prefix descriptor matches --> + <transition event="foo bar" target="s04"/> + </state> + +<state id="s04"> + <onentry> + <raise event="foos"/> + </onentry> + <!-- test that only token prefixes match --> + <transition event="foo" conf:targetfail=""/> + <transition event="foos" target="s05"/> +</state> + +<state id="s05"> + <onentry> + <raise event="foo.zoo"/> + </onentry> + <!-- test that .* works at the end of a descriptor --> + <transition event="foo.*" target="s06"/> + </state> + + <state id="s06"> + <onentry> + <raise event="foo"/> + </onentry> + <!-- test that "*" works by itself --> + <transition event="*" conf:targetpass=""/> + </state> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test401.txml b/test/samples/w3c/txml/test401.txml new file mode 100644 index 0000000..a42b719 --- /dev/null +++ b/test/samples/w3c/txml/test401.txml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- test that errors go in the internal event queue. We send ourselves an external event foo, then perform +and operation that raises an error. Then check that the error event is processed first, even though +it was raised second --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="foo"/> + <!-- assigning to a non-existent location should raise an error --> + <assign conf:location="1" conf:expr="2"/> + </onentry> + + + <transition event="foo" conf:targetfail=""/> + <transition event="error" conf:targetpass=""/> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test402.txml b/test/samples/w3c/txml/test402.txml new file mode 100644 index 0000000..24e84e1 --- /dev/null +++ b/test/samples/w3c/txml/test402.txml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<!-- the assertion that errors are 'like any other event' is pretty broad, but we can check that they +are pulled off the internal queue in order, and that prefix matching works on them. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <!-- catch the failure case --> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + + <state id="s01"> + <onentry> + <!-- the first internal event. The error will be the second, and event2 will be the third --> + <raise event="event1"/> + <!-- assigning to a non-existent location should raise an error --> + <assign conf:location="1" conf:expr="2"/> + </onentry> + + <transition event="event1" target="s02"> + <raise event="event2"/> + </transition> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s02"> + <transition event="error" target="s03"/> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s03"> + <transition event="event2" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test403a.txml b/test/samples/w3c/txml/test403a.txml new file mode 100644 index 0000000..88bc4dc --- /dev/null +++ b/test/samples/w3c/txml/test403a.txml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- we test one part of 'optimal enablement' meaning that of all transitions that are enabled, we chose the ones +in child states over parent states, and use document order to break ties. We have +a parent state s0 with two children, s01 and s02. In s01, we test that a) if +a transition in the child matches, we don't consider matches in the parent and b) +that if two transitions match in any state, we take the first in document order. +In s02 we test that we take a transition in the parent if there is no +matching transition in the child. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <!-- catch the failure case --> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + <transition event="event1" conf:targetfail=""/> + <transition event="event2" conf:targetpass=""/> + + <state id="s01"> + <onentry> + <!-- this should be caught by the first transition in this state, taking us to S02 --> + <raise event="event1"/> + </onentry> + + <transition event="event1" target="s02"/> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s02"> + <onentry> + <!-- since the local transition has a cond that evaluates to false this should be caught by a + transition in the parent state, taking us to pass --> + <raise event="event2"/> + </onentry> + <transition event="event1" conf:targetfail=""/> + <transition event="event2" conf:false="" conf:targetfail=""/> + </state> + +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test403b.txml b/test/samples/w3c/txml/test403b.txml new file mode 100644 index 0000000..c3ee1f8 --- /dev/null +++ b/test/samples/w3c/txml/test403b.txml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<!-- we test that 'optimally enabled set' really is a set, specifically that if a transition is optimally enabled in +two different states, it is taken only once. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + +<state id="s0" initial="p0"> + <!-- this transition should never be taken because a transition in a lower state should + always be selected --> + <transition event="event1"> + <conf:incrementID id="1"/> + </transition> + + + + <parallel id="p0"> + + <onentry> + <raise event="event1"/> + <raise event="event2"/> + </onentry> + + <!-- this transition will be selected by both states p0s1 and p0s2, but should be executed only once --> + <transition event="event1"> + <conf:incrementID id="1"/> + </transition> + + <state id="p0s1"> + <transition event="event2" conf:idVal="1=1" conf:targetpass=""/> + <transition event="event2" conf:targetfail=""/> + </state> + + <state id="p0s2"/> + +</parallel> +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test403c.txml b/test/samples/w3c/txml/test403c.txml new file mode 100644 index 0000000..8af1aac --- /dev/null +++ b/test/samples/w3c/txml/test403c.txml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<!-- we test 'optimally enabled set', specifically that preemption works correctly --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" expr="0"/> + </datamodel> + +<state id="s0" initial="p0"> + <onentry> + <raise event="event1"/> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="event2" conf:targetfail=""/> + <transition event="timeout" conf:targetfail=""/> + + <parallel id="p0"> + + <state id="p0s1"> + <transition event="event1"/> + <transition event="event2"/> + </state> + + <state id="p0s2"> + <transition event="event1" target="p0s1"> + <raise event="event2"/> + </transition> + + </state> + + <state id="p0s3"> + <!-- this transition should be blocked by the one in p0s2--> + <transition event="event1" conf:targetfail=""/> + <!-- this transition will preempt the one that p0s2 inherits + from an ancestor --> + <transition event="event2" target="s1"/> + + </state> + +<state id="p0s4"> + <!-- this transition never gets preempted, should fire twice --> + <transition event="*"> + <conf:incrementID id="1"/> + </transition> + </state> + +</parallel> +</state> + +<state id="s1"> + <transition conf:idVal="1=2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test404.txml b/test/samples/w3c/txml/test404.txml new file mode 100644 index 0000000..6734dbd --- /dev/null +++ b/test/samples/w3c/txml/test404.txml @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<!-- test that states are exited in exit order (children before parents with reverse doc order used to break ties + before the executable content in the transitions. event1, event2, event3, event4 should be raised in that + order when s01p is exited --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01p"> + + + +<parallel id="s01p"> + <onexit> + <!-- this should be the 3rd event raised --> + <raise event="event3"/> + </onexit> + <transition target="s02"> + <!-- this should be the fourth event raised --> + <raise event="event4"/> + </transition> + + <state id="s01p1"> + <onexit> + <!-- this should be the second event raised --> + <raise event="event2"/> + </onexit> + </state> + + <state id="s01p2"> + <!-- this should be the first event raised --> + <onexit> + <raise event="event1"/> + </onexit> + </state> + </parallel> + + <state id="s02"> + <transition event="event1" target="s03"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s03"> + <transition event="event2" target="s04"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s04"> + <transition event="event3" target="s05"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s05"> + <transition event="event4" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + </state> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test405.txml b/test/samples/w3c/txml/test405.txml new file mode 100644 index 0000000..ca8254e --- /dev/null +++ b/test/samples/w3c/txml/test405.txml @@ -0,0 +1,71 @@ +<?xml version="1.0"?> +<!-- test that the executable content in the transitions is executed in document order after +the states are exited. event1, event2, event3, event4 should be raised in that order when the +state machine is entered --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" + xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s0" initial="s01p"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + +<parallel id="s01p"> + <transition event="event1" target="s02"/> + + + <state id="s01p1" initial="s01p11"> + <state id="s01p11"> + <onexit> + <!-- this should be the second event raised --> + <raise event="event2"/> + </onexit> + <transition target="s01p12"> + <!-- this should be the third event raised --> + <raise event="event3"/> + </transition> + </state> + <state id="s01p12"/> + </state> <!-- end s01p1 --> + + <state id="s01p2" initial="s01p21"> + <state id="s01p21"> + <onexit> + <!-- this should be the first event raised --> + <raise event="event1"/> + </onexit> + <transition target="s01p22"> + <!-- this should be the fourth event raised --> + <raise event="event4"/> + </transition> + </state> + <state id="s01p22"/> + + </state> <!-- end s01p2 --> + </parallel> + + + <state id="s02"> + <transition event="event2" target="s03"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s03"> + <transition event="event3" target="s04"/> + <transition event="*" conf:targetfail=""/> + </state> + + + <state id="s04"> + <transition event="event4" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + </state> <!-- end s01 --> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test406.txml b/test/samples/w3c/txml/test406.txml new file mode 100644 index 0000000..9504381 --- /dev/null +++ b/test/samples/w3c/txml/test406.txml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- Test that states are entered in entry order (parents before children with document order used to break ties) +after the executable content in the transition is executed. event1, event2, event3, event4 should be raised in that +order when the transition in s01 is taken --> + +<scxml version="1.0" initial="s0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" + xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + + <state id="s01"> + <transition target="s0p2"> + <!-- this should be the first event raised --> + <raise event="event1"/> + </transition> + </state> + +<parallel id="s0p2"> + + <transition event="event1" target="s03"/> + + <state id="s01p21" > + <onentry> + <!-- third event --> + <raise event="event3"/> + </onentry> + </state> + + <state id="s01p22"> + <onentry> + <!-- the fourth event --> + <raise event="event4"/> + </onentry> + </state> + + <onentry> + <!-- this should be the second event raised --> + <raise event="event2"/> + </onentry> + </parallel> + + + <state id="s03"> + <transition event="event2" target="s04"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s04"> + <transition event="event3" target="s05"/> + <transition event="*" conf:targetfail=""/> + </state> + + + <state id="s05"> + <transition event="event4" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + </state> <!-- end s0 --> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test407.txml b/test/samples/w3c/txml/test407.txml new file mode 100644 index 0000000..fdef966 --- /dev/null +++ b/test/samples/w3c/txml/test407.txml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- a simple test that onexit handlers work. var1 should be incremented when we leave s0 --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + +<state id="s0"> + <onexit> + <conf:incrementID id="1"/> + </onexit> + <transition target="s1"/> +</state> + +<state id="s1"> + <transition conf:idVal="1=1" conf:targetpass=""/> + <transition conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test409.txml b/test/samples/w3c/txml/test409.txml new file mode 100644 index 0000000..abc92ee --- /dev/null +++ b/test/samples/w3c/txml/test409.txml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- we test that states are removed from the active states list as they are exited. When s01's onexit handler +fires, s011 should not be on the active state list, so in(S011) should be false, and event1 should not +be raised. Therefore the timeout should fire to indicate success --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + + <transition event="timeout" conf:targetpass=""/> + <transition event="event1" conf:targetfail=""/> + + <state id="s01" initial="s011"> + <onexit> + <if conf:inState="s011"> + <raise event="event1"/> + </if> + </onexit> + + <state id="s011"> + <transition target="s02"/> + </state> + </state> <!-- end s01 --> + +<state id="s02"/> + +</state> <!-- end s0 --> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test411.txml b/test/samples/w3c/txml/test411.txml new file mode 100644 index 0000000..149e21e --- /dev/null +++ b/test/samples/w3c/txml/test411.txml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- we test that states are added to the active states list as they are entered and before onentry handlers +are executed. When s0's onentry handler fires we should not be in s01. But when s01's onentry handler +fires, we should be in s01. Therefore event1 should not fire, but event2 should. Either event1 or +timeout also indicates failure --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="1s"/> + <if conf:inState="s01"> + <raise event="event1"/> + </if> + </onentry> + + <transition event="timeout" conf:targetfail=""/> + <transition event="event1" conf:targetfail=""/> + <transition event="event2" conf:targetpass=""/> + + <state id="s01" > + <onentry> + <if conf:inState="s01"> + <raise event="event2"/> + </if> + </onentry> + </state> + +</state> <!-- end s0 --> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test412.txml b/test/samples/w3c/txml/test412.txml new file mode 100644 index 0000000..6eb703f --- /dev/null +++ b/test/samples/w3c/txml/test412.txml @@ -0,0 +1,56 @@ +<?xml version="1.0"?> +<!-- test that executable content in the <initial> transition executes after the onentry handler on the state +and before the onentry handler of the child states. Event1, event2, and event3 should occur in that order. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + + <transition event="timeout" conf:targetfail=""/> + <transition event="event1" conf:targetfail=""/> + <transition event="event2" conf:targetpass=""/> + + <state id="s01" > + <onentry> + <raise event="event1"/> + </onentry> + <initial> + <transition target="s011"> + <raise event="event2"/> + </transition> + </initial> + + <state id="s011"> + <onentry> + <raise event="event3"/> + </onentry> + <transition target="s02"/> + </state> + </state> + +<state id="s02"> + <transition event="event1" target="s03"/> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s03"> + <transition event="event2" target="s04"/> + <transition event="*" conf:targetfail=""/> + </state> + +<state id="s04"> + <transition event="event3" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +</state> <!-- end s0 --> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test413.txml b/test/samples/w3c/txml/test413.txml new file mode 100644 index 0000000..0ac00e3 --- /dev/null +++ b/test/samples/w3c/txml/test413.txml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<!-- test that the state machine is put into the configuration specified by the initial element, without regard +to any other defaults. we should start off in s2p111 and s2p122. the atomic +states we should not enter all have immediate transitions to failure in them --> + + +<scxml initial="s2p112 s2p122" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s1"> + <transition conf:targetfail=""/> + </state> + +<state id="s2" initial="s2p1"> + +<parallel id="s2p1"> + <!-- this transition will be triggered only if we end up in an illegal configuration where we're in + either s2p112 or s2p122, but not both of them --> + <transition conf:targetfail=""/> + + <state id="s2p11" initial="s2p111" > + <state id="s2p111"> + <transition conf:targetfail=""/> + </state> + + <state id="s2p112"> + <transition conf:inState="s2p122" conf:targetpass=""/> + </state> + + </state> <!-- end s2p11 --> + + <state id="s2p12" initial="s2p121"> + <state id="s2p121"> + <transition conf:targetfail=""/> + </state> + + <state id="s2p122"> + <transition conf:inState="s2p112" conf:targetpass=""/> + </state> + </state> + +</parallel> + +</state> <!-- end s2 --> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test416.txml b/test/samples/w3c/txml/test416.txml new file mode 100644 index 0000000..bb0b6f5 --- /dev/null +++ b/test/samples/w3c/txml/test416.txml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- test that the done.state.id gets generated when we enter the final state of a compound state --> + + +<scxml version="1.0" initial="s1" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s1" initial="s11"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + + <state id="s11" initial="s111"> + <transition event="done.state.s11" conf:targetpass=""/> + <state id="s111"> + <transition target="s11final"/> + </state> + <final id="s11final"/> + </state> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test417.txml b/test/samples/w3c/txml/test417.txml new file mode 100644 index 0000000..5963d68 --- /dev/null +++ b/test/samples/w3c/txml/test417.txml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<!-- test that we get the done.state.id event when all of a +parallel elements children enter final states. --> + + + +<scxml version="1.0" initial="s1" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s1" initial="s1p1"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + + <parallel id="s1p1"> + <transition event="done.state.s1p1" conf:targetpass=""/> + + <state id="s1p11" initial="s1p111"> + <state id="s1p111"> + <transition target="s1p11final"/> + </state> + <final id="s1p11final"/> + </state> + + <state id="s1p12" initial="s1p121"> + <state id="s1p121"> + <transition target="s1p12final"/> + </state> + <final id="s1p12final"/> + </state> + + </parallel> +</state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test419.txml b/test/samples/w3c/txml/test419.txml new file mode 100644 index 0000000..2d8fab7 --- /dev/null +++ b/test/samples/w3c/txml/test419.txml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- test that eventless transitions take precedence over event-driven ones --> + + + +<scxml version="1.0" initial="s1" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s1"> + <onentry> + <raise event="internalEvent"/> + <send event="externalEvent"/> + </onentry> + + <transition event="*" conf:targetfail=""/> + <transition conf:targetpass=""/> + +</state> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test421.txml b/test/samples/w3c/txml/test421.txml new file mode 100644 index 0000000..4f92719 --- /dev/null +++ b/test/samples/w3c/txml/test421.txml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- test that internal events take priority over external ones, and that the processor +keeps pulling off internal events until it finds one that triggers a transition --> + + + +<scxml version="1.0" initial="s1" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s1" initial="s11"> + <onentry> + <send event="externalEvent"/> + <raise event="internalEvent1"/> + <raise event="internalEvent2"/> + <raise event="internalEvent3"/> + <raise event="internalEvent4"/> + </onentry> + + <transition event="externalEvent" conf:targetfail=""/> + + <state id="s11"> + <transition event="internalEvent3" target="s12"/> + </state> + + <state id="s12"> + <transition event="internalEvent4" conf:targetpass=""/> + </state> + +</state> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test422.txml b/test/samples/w3c/txml/test422.txml new file mode 100644 index 0000000..2e830d9 --- /dev/null +++ b/test/samples/w3c/txml/test422.txml @@ -0,0 +1,78 @@ +<?xml version="1.0"?> +<!-- Test that at the end of a macrostep, the processor executes all invokes in states +that have been entered and not exited during the step. (The invokes are supposed to be executed +in document order, but we can test that since each invocation is separate and they may take +different amounts to time to start up.) In this case, there are three invoke statements, +in states s1, s11 and s12. Each invoked process returns an event named after its parent state. +The invokes in s1 and s12 should execute, but not the one +in s11. So we should receive invokeS1, invokeS12, but not invokeS12. Furthermore, when the timeout fires, var1 should equal 2.--> + +<scxml version="1.0" initial="s1" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> + </datamodel> + <state id="s1" initial="s11"> + <onentry> + <send event="timeout" delay="5s"/> + </onentry> + <transition event="invokeS1 invokeS12"> + <conf:incrementID id="1"/> + </transition> + <transition event="invokeS11" conf:targetfail=""/> + + <transition event="timeout" conf:idVal="1=2" conf:targetpass=""/> + <transition event="timeout" conf:targetfail=""/> + <invoke> + <content> + <!-- when invoked, send 'foo' to parent, then terminate. --> + <scxml initial="sub0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub0"> + <onentry> + <send target="#_parent" event="invokeS1"/> + </onentry> + <transition target="subFinal0"/> + </state> + <final id="subFinal0"/> + </scxml> + </content> + </invoke> + + <state id="s11"> + <invoke> + <content> + <!-- when invoked, send 'foo' to parent, then terminate. --> + <scxml initial="sub1" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub1"> + <onentry> + <send target="#_parent" event="invokeS11"/> + </onentry> + <transition target="subFinal1"/> + </state> + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <transition target="s12"/> + </state> + <state id="s12"> + <invoke> + <content> + <!-- when invoked, send 'foo' to parent, then terminate. --> + <scxml initial="sub2" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <state id="sub2"> + <onentry> + <send target="#_parent" event="invokeS12"/> + </onentry> + <transition target="subFinal2"/> + </state> + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + </state> + </state> + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test423.txml b/test/samples/w3c/txml/test423.txml new file mode 100644 index 0000000..fd64587 --- /dev/null +++ b/test/samples/w3c/txml/test423.txml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- test that we keep pulling external events off the queue till we find one that matches a transition. --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + + <state id="s0"> + <onentry> + <send event="externalEvent1"/> + <send event="externalEvent2" delay="1s"/> + <raise event="internalEvent"/> + </onentry> + <!-- in this state we should process only internalEvent --> + <transition event="internalEvent" target="s1"/> + <transition event="*" conf:targetfail=""/> + </state> + + <state id="s1"> + <!-- in this state we ignore externalEvent1 and wait for externalEvent2 --> + <transition event="externalEvent2" conf:targetpass=""/> + <transition event="internalEvent" conf:targetfail=""/> + </state> + + + <conf:pass/> + <conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test487.txml b/test/samples/w3c/txml/test487.txml new file mode 100644 index 0000000..7210c2b --- /dev/null +++ b/test/samples/w3c/txml/test487.txml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- test illegal assignment. error.execution should be raised. --> + + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:illegalExpr=""/> + </datamodel> + +<state id="s0"> + <onentry> + <raise event="event"/> + </onentry> + + <transition event="error.execution" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test488.txml b/test/samples/w3c/txml/test488.txml new file mode 100644 index 0000000..c0bb5e4 --- /dev/null +++ b/test/samples/w3c/txml/test488.txml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- test that illegal expr in <param> produces error.execution and empty event.data --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" conf:datamodel="" initial="s0"> + + + <state id="s0" initial="s01"> + <!-- we should get the error before the done event --> + <transition event="error.execution" target="s1"/> + <transition event="done.state.s0" conf:targetfail=""/> + + <transition event="done.state.s0" conf:targetfail=""> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <param conf:illegalExpr="" name="someParam"/> + </donedata> + </final> + </state> + + + <!-- if we get here, we received the error event. Now check that the done + event has empty event.data --> + + <state id="s1"> + <transition event="done.state.s0" conf:eventdataVal="" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test503.txml b/test/samples/w3c/txml/test503.txml new file mode 100644 index 0000000..d15bb7e --- /dev/null +++ b/test/samples/w3c/txml/test503.txml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> + +<!-- test that a targetless transition does not exit and reenter its source state --> + +<scxml initial="s1" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> <!-- how often we have exited s2 --> + <data conf:id="2" conf:expr="0"/> <!-- how often the targetless transition in s2 has been executed --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition target="s2"/> + </state> + + <state id="s2"> + <onexit> + <conf:incrementID id="1"/> + </onexit> + <transition event="foo"> + <conf:incrementID id="2"/> + </transition> + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" conf:idVal="2=1" target="s3"/> + <transition event="bar" conf:targetfail=""/> + </state> + + <state id="s3"> + <!-- make sure that s2 was exited only once --> + <transition conf:idVal="1=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test504.txml b/test/samples/w3c/txml/test504.txml new file mode 100644 index 0000000..62f601b --- /dev/null +++ b/test/samples/w3c/txml/test504.txml @@ -0,0 +1,79 @@ +<?xml version="1.0"?> + +<!-- test that an external transition exits all states up the the LCCA --> + +<scxml initial="s1" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> <!-- how often we have exited p --> + <data conf:id="2" conf:expr="0"/> <!-- how often we have exited ps1 --> + <data conf:id="3" conf:expr="0"/> <!-- how often we have exited ps2 --> + <data conf:id="4" conf:expr="0"/> <!-- how often the transition for foo has been taken --> + <data conf:id="5" conf:expr="0"/> <!-- how often we have exited s2 --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition target="p"/> + </state> + +<state id="s2"> + <onexit> + <conf:incrementID id="5"/> + </onexit> + +<parallel id="p"> + <onexit> + <conf:incrementID id="1"/> + </onexit> + <transition event="foo" target="ps1"> + <conf:incrementID id="4"/> + </transition> + + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" conf:idVal="4=1" target="s3"/> + <transition event="bar" conf:targetfail=""/> + + <state id="ps1"> + <onexit> + <conf:incrementID id="2"/> + </onexit> + </state> + <state id="ps2"> + <onexit> + <conf:incrementID id="3"/> + </onexit> + </state> +</parallel> +</state> + +<state id="s3"> + <!-- make sure that p was exited twice --> + <transition conf:idVal="1=2" target="s4"/> + <transition conf:targetfail=""/> + </state> + +<state id="s4"> + <!-- make sure that ps1 was exited twice --> + <transition conf:idVal="2=2" target="s5"/> + <transition conf:targetfail=""/> + </state> + +<state id="s5"> + <!-- make sure that ps2 was exited twice --> + <transition conf:idVal="3=2" target="s6"/> + <transition conf:targetfail=""/> + </state> + +<state id="s6"> + <!-- make sure that s1 was exited once --> + <transition conf:idVal="5=1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test505.txml b/test/samples/w3c/txml/test505.txml new file mode 100644 index 0000000..b141186 --- /dev/null +++ b/test/samples/w3c/txml/test505.txml @@ -0,0 +1,51 @@ +<?xml version="1.0"?> + +<!-- test that an internal transition does not exit its source state --> + +<scxml initial="s1" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> <!-- how often we have exited s1 --> + <data conf:id="2" conf:expr="0"/> <!-- how often we have exited s11 --> + <data conf:id="3" conf:expr="0"/> <!-- how often the transition for foo has been taken --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <onexit> + <conf:incrementID id="1"/> + </onexit> + <transition event="foo" type="internal" target="s11"> + <conf:incrementID id="3"/> + </transition> + + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" conf:idVal="3=1" target="s2"/> + <transition event="bar" conf:targetfail=""/> + + <state id="s11"> + <onexit> + <conf:incrementID id="2"/> + </onexit> + </state> + </state> + +<state id="s2"> + <!-- make sure that s1 was exited once --> + <transition conf:idVal="1=1" target="s3"/> + <transition conf:targetfail=""/> + </state> + + +<state id="s3"> + <!-- make sure that s11 was exited twice --> + <transition conf:idVal="2=2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test506.txml b/test/samples/w3c/txml/test506.txml new file mode 100644 index 0000000..b820ad5 --- /dev/null +++ b/test/samples/w3c/txml/test506.txml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> + +<!-- test that an internal transition whose targets are not proper descendants of its source state +behaves like an external transition --> + +<scxml initial="s1" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> <!-- how often we have exited s2 --> + <data conf:id="2" conf:expr="0"/> <!-- how often we have exited s21 --> + <data conf:id="3" conf:expr="0"/> <!-- how often the transition for foo has been taken --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition target="s2"/> + </state> + +<state id="s2" initial="s21"> + <onexit> + <conf:incrementID id="1"/> + </onexit> + <transition event="foo" type="internal" target="s2"> + <conf:incrementID id="3"/> + </transition> + + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" conf:idVal="3=1" target="s3"/> + <transition event="bar" conf:targetfail=""/> + + <state id="s21"> + <onexit> + <conf:incrementID id="2"/> + </onexit> + </state> + +</state> + +<state id="s3"> + <!-- make sure that s2 was exited twice --> + <transition conf:idVal="1=2" target="s4"/> + <transition conf:targetfail=""/> + </state> + +<state id="s4"> + <!-- make sure that s21 was exited twice --> + <transition conf:idVal="2=2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test521.txml b/test/samples/w3c/txml/test521.txml new file mode 100644 index 0000000..75743ef --- /dev/null +++ b/test/samples/w3c/txml/test521.txml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- we test that the processor raises error.communication if it cannot dispatch the event. +(To create an undispatchable event, we choose a non-existent session as target). If it raises +the error event, we succeed. Otherwise we eventually timeout and fail. --> + + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <!-- should cause an error --> + <send conf:unreachableTarget="" event="event2"/> + <!-- this will get added to the external event queue after the error has been raised --> + <send event="timeout"/> + </onentry> + + <!-- once we've entered the state, we should check for internal events first --> + <transition event="error.communication" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test525.txml b/test/samples/w3c/txml/test525.txml new file mode 100644 index 0000000..4b367eb --- /dev/null +++ b/test/samples/w3c/txml/test525.txml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- test that <foreach> does a shallow copy, so that modifying the array does not change +the iteration behavior. --> + + +<scxml conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1"> + <conf:array123/> + </data> + <data conf:id="2" conf:expr="0"/> <!-- counts the number of iterations --> + </datamodel> + +<state id="s0"> + <onentry> + <foreach conf:item="3" conf:arrayVar="1"> + <conf:extendArray id="1"/> + <conf:incrementID id="2"/> + </foreach> + </onentry> + + <transition conf:idVal="2=3" conf:targetpass=""/> + <transition conf:targetfail=""/> +</state> + + + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test527.txml b/test/samples/w3c/txml/test527.txml new file mode 100644 index 0000000..80894a7 --- /dev/null +++ b/test/samples/w3c/txml/test527.txml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- simple test that 'expr' works with <content> --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" conf:datamodel="" initial="s0"> + + + <state id="s0" initial="s01"> + + <transition event="done.state.s0" conf:eventdataVal="foo" conf:targetpass=""> + </transition> + + <transition event="done.state.s0" conf:targetfail=""> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <content conf:quoteExpr="foo"/> + </donedata> + </final> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test528.txml b/test/samples/w3c/txml/test528.txml new file mode 100644 index 0000000..69b7bb2 --- /dev/null +++ b/test/samples/w3c/txml/test528.txml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- test that illegal 'expr' produces error.execution and empty event.data --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" conf:datamodel="" initial="s0"> + + + <state id="s0" initial="s01"> + <!-- we should get the error before the done event --> + <transition event="error.execution" target="s1"/> + <transition event="done.state.s0" conf:targetfail=""/> + + <transition event="done.state.s0" conf:targetfail=""> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <content conf:illegalExpr=""/> + </donedata> + </final> + </state> + + + <!-- if we get here, we received the error event. Now check that the done + event has empty event.data --> + + <state id="s1"> + <transition event="done.state.s0" conf:emptyEventData="" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test529.txml b/test/samples/w3c/txml/test529.txml new file mode 100644 index 0000000..6a6656c --- /dev/null +++ b/test/samples/w3c/txml/test529.txml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- simple test that children workn with <content> --> + +<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" conf:datamodel="" initial="s0"> + + + <state id="s0" initial="s01"> + + <transition event="done.state.s0" conf:eventdataVal="21" conf:targetpass=""> + </transition> + + <transition event="done.state.s0" conf:targetfail=""> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <content>21</content> + </donedata> + </final> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test530.txml b/test/samples/w3c/txml/test530.txml new file mode 100644 index 0000000..d64a8d8 --- /dev/null +++ b/test/samples/w3c/txml/test530.txml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- test that <content> child is evaluated when <invoke> is. Var1 is initialized +with an integer value, then set to an scxml script in the onentry to s0. If <content> +is evaluated at the right time, we should get invoke.done, otherwise an error --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" conf:expr="1"/> + </datamodel> + + <state id="s0"> + <onentry> + <assign conf:location="1"> + <scxml version="1.0"><final/></scxml> + </assign> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/"> + <content conf:varChildExpr="1"/> + </invoke> + + <transition event="done.invoke" conf:targetpass=""/> + <transition event="*" conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + </scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test533.txml b/test/samples/w3c/txml/test533.txml new file mode 100644 index 0000000..7a6c82a --- /dev/null +++ b/test/samples/w3c/txml/test533.txml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> + +<!-- test that an internal transition whose source state is not compound does exit its source state --> + +<scxml initial="s1" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> +<datamodel> + <data conf:id="1" conf:expr="0"/> <!-- how often we have exited p --> + <data conf:id="2" conf:expr="0"/> <!-- how often we have exited ps1 --> + <data conf:id="3" conf:expr="0"/> <!-- how often we have exited ps2 --> + <data conf:id="4" conf:expr="0"/> <!-- how often the transition for foo has been taken --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition target="p"/> + </state> + +<parallel id="p"> + <onexit> + <conf:incrementID id="1"/> + </onexit> + <transition event="foo" type="internal" target="ps1"> + <conf:incrementID id="4"/> + </transition> + + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" conf:idVal="4=1" target="s2"/> + <transition event="bar" conf:targetfail=""/> + + <state id="ps1"> + <onexit> + <conf:incrementID id="2"/> + </onexit> + </state> + <state id="ps2"> + <onexit> + <conf:incrementID id="3"/> + </onexit> + </state> +</parallel> + +<state id="s2"> + <!-- make sure that p was exited twice --> + <transition conf:idVal="1=2" target="s3"/> + <transition conf:targetfail=""/> + </state> + +<state id="s3"> + <!-- make sure that ps1 was exited twice --> + <transition conf:idVal="2=2" target="s4"/> + <transition conf:targetfail=""/> + </state> + +<state id="s4"> + <!-- make sure that ps2 was exited twice --> + <transition conf:idVal="3=2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test550.txml b/test/samples/w3c/txml/test550.txml new file mode 100644 index 0000000..89f55a7 --- /dev/null +++ b/test/samples/w3c/txml/test550.txml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> + +<!-- test that expr can be used to assign a value to a var. This test uses early binding --> + +<scxml initial="s0" version="1.0" conf:datamodel="" binding="early" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + <state id="s0"> + + <transition conf:idVal="1=2" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <state id="s1"> + <datamodel> + <data conf:id="1" conf:expr="2"/> + </datamodel> + </state> + + <conf:pass/> + <conf:fail/> + + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test551.txml b/test/samples/w3c/txml/test551.txml new file mode 100644 index 0000000..45c6bf8 --- /dev/null +++ b/test/samples/w3c/txml/test551.txml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> + +<!-- test that inline content can be used to assign a value to a var. --> + +<scxml initial="s0" version="1.0" binding="early" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + + <state id="s0"> + + <transition conf:isBound="1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + +<state id="s1"> + <datamodel> + <data conf:id="1"> + <conf:array123/> + </data> + </datamodel> + </state> + + <conf:pass/> + <conf:fail/> + + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test552.txml b/test/samples/w3c/txml/test552.txml new file mode 100644 index 0000000..9489b3e --- /dev/null +++ b/test/samples/w3c/txml/test552.txml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> + +<!-- test that src content can be used to assign a value to a var. Edit +test552.txt to have a value that's legal for the datamodel in question --> + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <datamodel> + <data conf:id="1" src="file:test552.txt"/> + </datamodel> + + <state id="s0"> + + <transition conf:isBound="1" conf:targetpass=""/> + <transition conf:targetfail=""/> + </state> + + <conf:pass/> + <conf:fail/> + + + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test553.txml b/test/samples/w3c/txml/test553.txml new file mode 100644 index 0000000..322d4bb --- /dev/null +++ b/test/samples/w3c/txml/test553.txml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- we test that the processor does not dispatch the event if evaluation +of <send>'s args causes an error.. --> + + +<scxml initial="s0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <!-- timeout event --> + <send event="timeout" delay="3s"/> + <!-- include a non-existing var in the namelist --> + <send event="event1" conf:namelist="2"/> + </onentry> + + <!-- if we get the timeout before event1, we assume that event1 hasn't been sent + We ignore the error event here because this assertion doesn't mention it --> + <transition event="timeout" conf:targetpass=""/> + <transition event="event1" conf:targetfail=""/> + </state> + + +<conf:pass/> +<conf:fail/> + +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test554.txml b/test/samples/w3c/txml/test554.txml new file mode 100644 index 0000000..d9ad55b --- /dev/null +++ b/test/samples/w3c/txml/test554.txml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- test that if the evaluation of <invoke>'s args causes an error, the +invocation is cancelled. In this test, that means that we don't get done.invoke +before the timer goes off. --> + + +<scxml initial="s0" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <onentry> + <send event="timer" delay="2s"/> + </onentry> + + <!-- namelist references an undeclared variable --> + <invoke type="http://www.w3.org/TR/scxml/" conf:namelist="2"> + <content> + <scxml initial="subFinal" version="1.0" conf:datamodel="" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="timer" conf:targetpass=""/> + <transition event="done.invoke" conf:targetfail=""/> + </state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test570.txml b/test/samples/w3c/txml/test570.txml new file mode 100644 index 0000000..6584d9a --- /dev/null +++ b/test/samples/w3c/txml/test570.txml @@ -0,0 +1,49 @@ +<?xml version="1.0"?>
+
+<!-- test that we generate done.state.id when all a parallel state's children are in final states -->
+
+<scxml initial="p0" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance">
+ <datamodel>
+ <data conf:id="1" conf:expr="0"/>
+ </datamodel>
+<parallel id="p0">
+ <onentry>
+ <send event="timeout" delay="2s"/>
+ <raise event="e1"/>
+ <raise event="e2"/>
+ </onentry>
+ <!-- record that we get the first done event -->
+ <transition event="done.state.p0s1">
+ <assign conf:location="1" conf:expr="1"/>
+ </transition>
+ <!-- we should get the second done event before done.state.p0 -->
+ <transition event="done.state.p0s2" target="s1"/>
+ <transition event="timeout" conf:targetfail=""/>
+
+
+ <state id="p0s1" initial="p0s11">
+ <state id="p0s11">
+ <transition event="e1" target="p0s1final"/>
+ </state>
+ <final id="p0s1final"/>
+ </state>
+
+ <state id="p0s2" initial="p0s21">
+ <state id="p0s21">
+ <transition event="e2" target="p0s2final"/>
+ </state>
+ <final id="p0s2final"/>
+ </state>
+
+ </parallel>
+
+ <state id="s1">
+ <!-- if we get done.state.p0, success -->
+ <transition event="done.state.p0" conf:idVal="1=1" conf:targetpass=""/>
+ <transition event="*" conf:targetfail=""/>
+ </state>
+
+ <conf:pass/>
+ <conf:fail/>
+
+</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/txml/test576.txml b/test/samples/w3c/txml/test576.txml new file mode 100644 index 0000000..4c4b34a --- /dev/null +++ b/test/samples/w3c/txml/test576.txml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<!-- test that the 'initial' value of scxml is respected. We set the value to deeply nested non-default parallel siblings and +test that both are entered. --> + + +<scxml initial="s11p112 s11p122" conf:datamodel="" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance"> + + +<state id="s0"> + <transition conf:targetfail=""/> +</state> + +<state id="s1"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" conf:targetfail=""/> + <state id="s11" initial="s111"> + <state id="s111"/> + <parallel id="s11p1"> + <state id="s11p11" initial="s11p111"> + <state id="s11p111"/> + <state id="s11p112"> + <onentry> + <raise event="In-s11p112"/> + </onentry> + </state> + </state> + <state id="s11p12" initial="s11p121"> + <state id="s11p121"/> + <state id="s11p122"> + <transition event="In-s11p112" conf:targetpass=""/> + </state> + </state> + </parallel> + </state> +</state> + +<conf:pass/> +<conf:fail/> +</scxml>
\ No newline at end of file diff --git a/test/samples/w3c/update-txml.sh b/test/samples/w3c/update-txml.sh new file mode 100755 index 0000000..dab3cf3 --- /dev/null +++ b/test/samples/w3c/update-txml.sh @@ -0,0 +1,4 @@ +#!/bin/bash +wget -rl1 http://www.w3.org/Voice/2013/scxml-irp/ +find ./www.w3.org -name *.txml -exec cp {} ./txml \; +rm -rf www.w3.org
\ No newline at end of file diff --git a/test/scxml-test-framework/test/w3c/test144.txml.json b/test/scxml-test-framework/test/w3c/test144.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test144.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test144.txml.scxml b/test/scxml-test-framework/test/w3c/test144.txml.scxml new file mode 100644 index 0000000..e400119 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test144.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- test that events are inserted into the queue in the order in which they are raised. If +foo occurs before bar, success, otherwise failure --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition event="foo" target="s1"/> + <transition event="*" target="fail"/> + + </state> + +<state id="s1"> + <transition event="bar" target="pass"/> + <transition event="*" target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test147.txml.json b/test/scxml-test-framework/test/w3c/test147.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test147.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test147.txml.scxml b/test/scxml-test-framework/test/w3c/test147.txml.scxml new file mode 100644 index 0000000..ff523d3 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test147.txml.scxml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- test that the first clause that evaluates to true - and only that clause - is executed. +Only one event should be raised, and it should be bar --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <if cond="false"> + <raise event="foo"/> + <assign location="Var1" expr="Var1 + 1"/> + <elseif cond="true"/> + <raise event="bar"/> + <assign location="Var1" expr="Var1 + 1"/> + <else/> + <raise event="baz"/> + <assign location="Var1" expr="Var1 + 1"/> + </if> + <raise event="bat"/> + </onentry> + <transition event="bar" cond="" target="pass"/> + <transition event="*" target="fail"/> + + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test148.txml.json b/test/scxml-test-framework/test/w3c/test148.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test148.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test148.txml.scxml b/test/scxml-test-framework/test/w3c/test148.txml.scxml new file mode 100644 index 0000000..66287ee --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test148.txml.scxml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- test that the else clause executes if <if> and <elseif> evaluate to false. +Baz should be the only event generated by the <if>. bat is raised to catch the case where the <else> clause +fails and baz is not generated, i.e. it makes sure that the test doesn't hang. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <if cond="false"> + <raise event="foo"/> + <assign location="Var1" expr="Var1 + 1"/> + <elseif cond="false"/> + <raise event="bar"/> + <assign location="Var1" expr="Var1 + 1"/> + <else/> + <raise event="baz"/> + <assign location="Var1" expr="Var1 + 1"/> + </if> + <raise event="bat"/> + </onentry> + <transition event="baz" cond="" target="pass"/> + <transition event="*" target="fail"/> + + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test149.txml.json b/test/scxml-test-framework/test/w3c/test149.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test149.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test149.txml.scxml b/test/scxml-test-framework/test/w3c/test149.txml.scxml new file mode 100644 index 0000000..d40bf80 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test149.txml.scxml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- test that neither if clause executes, so that bat is the only event raised. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <if cond="false"> + <raise event="foo"/> + <assign location="Var1" expr="Var1 + 1"/> + <elseif cond="false"/> + <raise event="bar"/> + <assign location="Var1" expr="Var1 + 1"/> + </if> + <raise event="bat"/> + </onentry> + <transition event="bat" cond="" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test150.txml.json b/test/scxml-test-framework/test/w3c/test150.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test150.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test150.txml.scxml b/test/scxml-test-framework/test/w3c/test150.txml.scxml new file mode 100644 index 0000000..b2d239c --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test150.txml.scxml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<!-- test that foreach causes a new variable to be declared if 'item' doesn't already exist. Also +test that it will use an existing var if it does exist. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1"/> + <data id="Var2"/> + <data id="Var3"> + [1,2,3] + </data> + </datamodel> + + <state id="s0"> + <onentry> +<!-- first use declared variables --> + <foreach item="Var1" index="Var2" array="Var3"/> + <raise event="foo"/> + </onentry> + <transition event="error" target="fail"/> + <transition event="*" target="s1"/> + </state> + +<state id="s1"> + <onentry> +<!-- now use undeclared variables --> + <foreach item="Var4" index="Var5" array="Var3"/> + <raise event="bar"/> + </onentry> + <transition event="error" target="fail"/> + <transition event="*" target="s2"/> + </state> + +<state id="s2"> + <!-- check that var4 is bound --> + <transition cond="Var4" target="pass"/> + <transition target="fail"/> + </state> + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test151.txml.json b/test/scxml-test-framework/test/w3c/test151.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test151.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test151.txml.scxml b/test/scxml-test-framework/test/w3c/test151.txml.scxml new file mode 100644 index 0000000..76454b4 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test151.txml.scxml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<!-- test that foreach causes a new variable to be declared if 'item' doesn't already exist. Also +test that it will use an existing var if it does exist. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1"/> + <data id="Var2"/> + <data id="Var3"> + [1,2,3] + </data> + </datamodel> + + <state id="s0"> + <onentry> +<!-- first use declared variables --> + <foreach item="Var1" index="Var2" array="Var3"/> + <raise event="foo"/> + </onentry> + <transition event="error" target="fail"/> + <transition event="*" target="s1"/> + </state> + +<state id="s1"> + <onentry> +<!-- now use undeclared variables --> + <foreach item="Var4" index="Var5" array="Var3"/> + <raise event="bar"/> + </onentry> + <transition event="error" target="fail"/> + <transition event="*" target="s2"/> + </state> + +<state id="s2"> + <!-- check that var5 is bound --> + <transition cond="Var5" target="pass"/> + <transition target="fail"/> + </state> + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test152.txml.json b/test/scxml-test-framework/test/w3c/test152.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test152.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test152.txml.scxml b/test/scxml-test-framework/test/w3c/test152.txml.scxml new file mode 100644 index 0000000..affd58b --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test152.txml.scxml @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<!-- test that an illegal array or item value causes error.execution and results in executable content +not being executed. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1" expr="0"/> + <data id="Var2"/> + <data id="Var3"/> + <data id="Var4" expr="7"/> + <data id="Var5"> + [1,2,3] + </data> + </datamodel> + + <state id="s0"> + <onentry> +<!-- invalid array, legal item --> + <foreach item="Var2" index="Var3" array="Var4"> + <assign location="Var1" expr="Var1 + 1"/> + </foreach> + <raise event="foo"/> + </onentry> + <transition event="error.execution" target="s1"/> + <transition event="*" target="fail"/> + </state> + + <state id="s1"> + <onentry> +<!-- illegal item, legal array --> + <foreach item="'continue'" index="Var3" array="Var5"> + <assign location="Var1" expr="Var1 + 1"/> + </foreach> + <raise event="bar"/> + </onentry> + <transition event="error.execution" target="s2"/> + <transition event="bar" target="fail"/> + </state> + +<state id="s2"> + <!-- check that var1 has its original value (so executable content never got executed --> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test153.txml.json b/test/scxml-test-framework/test/w3c/test153.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test153.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test153.txml.scxml b/test/scxml-test-framework/test/w3c/test153.txml.scxml new file mode 100644 index 0000000..0664741 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test153.txml.scxml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- test that foreach goes over the array in the right order. since the array contains 1 2 3, we compare the current +value with the previous value, which is stored in var1. The current value should always be larger. If +it ever isn't, set Var4 to 0, indicating failure --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> <!-- contains the previous value --> + <data id="Var2"/> <!-- the item which will contain the current value --> + <data id="Var3"> + [1,2,3] + </data> + <data id="Var4" expr="1"/> <!-- 1 if success, 0 if failure --> + </datamodel> + + <state id="s0"> + <onentry> + <foreach item="Var2" array="Var3"> + <if cond=""> + <assign location="Var1" expr="Var2"/> + <else/> + <!-- values are out of order, record failure --> + <assign location="Var4" expr="0"/> + </if> + </foreach> + </onentry> + + <!-- check that var1 has its original value --> + <transition cond="" target="fail"/> + <transition target="pass"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test155.txml.json b/test/scxml-test-framework/test/w3c/test155.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test155.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test155.txml.scxml b/test/scxml-test-framework/test/w3c/test155.txml.scxml new file mode 100644 index 0000000..451f106 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test155.txml.scxml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- test that foreach executes the executable content once for each item in the list '(1,2,3)'. The executable +content sums the items into var1 so it should be 6 at the end --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + +<datamodel> + <data id="Var1" expr="0"/> + <data id="Var2"/> + <data id="Var3"> + [1,2,3] + </data> + </datamodel> + + <state id="s0"> + <onentry> + <foreach item="Var2" array="Var3"> + <assign location="Var1" expr="Var1 + Var2"/> + </foreach> + </onentry> + + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test156.txml.json b/test/scxml-test-framework/test/w3c/test156.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test156.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test156.txml.scxml b/test/scxml-test-framework/test/w3c/test156.txml.scxml new file mode 100644 index 0000000..70055c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test156.txml.scxml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- test that an error causes the foreach to stop execution. The second piece of executable content +should cause an error, so var1 should be incremented only once --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + +<datamodel> + <data id="Var1" expr="0"/> + <data id="Var2"/> + <data id="Var3"> + [1,2,3] + </data> + </datamodel> + + <state id="s0"> + <onentry> + <foreach item="Var2" array="Var3"> + <assign location="Var1" expr="Var1 + 1"/> + <!-- assign an illegal value to a non-existent var --> + <assign location="Var5" expr="return"/> + </foreach> + </onentry> + + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test158.txml.json b/test/scxml-test-framework/test/w3c/test158.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test158.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test158.txml.scxml b/test/scxml-test-framework/test/w3c/test158.txml.scxml new file mode 100644 index 0000000..6cf598a --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test158.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- test that executable content executes in document order. if event1 occurs then event2, succeed, otherwise fail --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1" expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <raise event="event1"/> + <raise event="event2"/> + </onentry> + <transition event="event1" target="s1"/> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> + <transition event="event2" target="pass"/> + <transition event="*" target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test159.txml.json b/test/scxml-test-framework/test/w3c/test159.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test159.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test159.txml.scxml b/test/scxml-test-framework/test/w3c/test159.txml.scxml new file mode 100644 index 0000000..758c228 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test159.txml.scxml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- test that any error raised by an element of executable content causes all subsequent elements to be skipped. +The send tag will raise an error so var1 should not be incremented. If it is fail, otherwise succeed --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1" expr="0"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="thisWillFail" conf:illegaltarget=""/> + <conf:incrementId id="1"/> + </onentry> + <transition cond="" target="fail"/> + <transition target="pass"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test172.txml.json b/test/scxml-test-framework/test/w3c/test172.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test172.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test172.txml.scxml b/test/scxml-test-framework/test/w3c/test172.txml.scxml new file mode 100644 index 0000000..2dfb10f --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test172.txml.scxml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- we test that eventexpr uses the current value of var1, not its initial value --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1" expr="'event1'"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign location="Var1" expr="'event2'"/> + <send eventexpr="Var1"/> + </onentry> + + <transition event="event2" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test173.txml.json b/test/scxml-test-framework/test/w3c/test173.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test173.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test173.txml.scxml b/test/scxml-test-framework/test/w3c/test173.txml.scxml new file mode 100644 index 0000000..5a11c24 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test173.txml.scxml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- we test that targetexpr uses the current value of var1, not its initial value +(If it uses the initial value, it will generate an error. If it uses the current value, event1 will be raised --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="27"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign location="Var1" expr="'#_internal'"/> + <send targetexpr="Var1" event="event1"/> + </onentry> + + <transition event="event1" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test174.txml.json b/test/scxml-test-framework/test/w3c/test174.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test174.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test174.txml.scxml b/test/scxml-test-framework/test/w3c/test174.txml.scxml new file mode 100644 index 0000000..f4ee03f --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test174.txml.scxml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- we test that typeexpr uses the current value of var1, not its initial value +(If it uses the initial value, it will generate an error. If it uses the current value, event1 will be raised --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1" expr="27"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign location="Var1" expr="'http://www.w3.org/TR/scxml/#SCXMLEventProcessor'"/> + <send typeexpr="Var1" event="event1"/> + </onentry> + + <transition event="event1" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test175.txml.json b/test/scxml-test-framework/test/w3c/test175.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test175.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test175.txml.scxml b/test/scxml-test-framework/test/w3c/test175.txml.scxml new file mode 100644 index 0000000..1e47f7e --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test175.txml.scxml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- we test that delayexpr uses the current value of var1, not its initial value +(If it uses the initial value, event2 will be generated first, before event1. If it uses the current value, +event1 will be raised first. Succeed if event1 occurs before event2, otherwise fail --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="'0s'"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign location="Var1" expr="'3s'"/> + <send delayexpr="Var1" event="event2"/> + <send delay="1s" event="event1"/> + </onentry> + + <transition event="event1" target="s1"/> + <transition event="event2" target="fail"/> + </state> + +<state id="s1"> + <transition event="event2" target="pass"/> + <transition event="*" target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test176.txml.json b/test/scxml-test-framework/test/w3c/test176.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test176.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test176.txml.scxml b/test/scxml-test-framework/test/w3c/test176.txml.scxml new file mode 100644 index 0000000..7341f24 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test176.txml.scxml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- we test that <param> uses the current value of var1, not its initial value. If the value of +aParam in event1 is 2 so that var2 gets set to 2, success, otherwise failure --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="1"/> + <data id="Var2"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign location="Var1" expr="2"/> + <send event="event1"> + <param name="aParam" expr="Var1"/> + </send> + </onentry> + + <transition event="event1" target="s1"> + <assign location="Var2" expr="_event.data.aParam"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test178.txml.json b/test/scxml-test-framework/test/w3c/test178.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test178.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test178.txml.scxml b/test/scxml-test-framework/test/w3c/test178.txml.scxml new file mode 100644 index 0000000..e9e243e --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test178.txml.scxml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- we test that multiple key/value pairs are included, even when the keys are the same. +This is a manual test. The tester must look at the log output and verify that both +keys are there. (This test uses the SCXML Event I/O processor, which is the only +one that all platforms must support. It does not specify the message format, so +we cannot test _event.raw directly. Therefore we print it out for visual +inspection.) --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + +<state id="s0"> + <onentry> + <send event="event1"> + <param name="Var1" expr="2"/> + <param name="Var1" expr="3"/> + </send> + </onentry> + + <transition event="event1" target="final"> + <log label="_event " expr="_event.raw"/> + </transition> + <transition event="*" target="fail"/> + + </state> + + +<final id="final"/> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test179.txml.json b/test/scxml-test-framework/test/w3c/test179.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test179.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test179.txml.scxml b/test/scxml-test-framework/test/w3c/test179.txml.scxml new file mode 100644 index 0000000..861a681 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test179.txml.scxml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- we test that <content> can be used to populate body of a message --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="event1"> + <content>123</content> + </send> + </onentry> + + <transition event="event1" cond="_event.data === '123'" target="pass"/> + <transition event="*" target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test183.txml.json b/test/scxml-test-framework/test/w3c/test183.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test183.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test183.txml.scxml b/test/scxml-test-framework/test/w3c/test183.txml.scxml new file mode 100644 index 0000000..73b7797 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test183.txml.scxml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- we test that <send> stores the value of the sendid in idlocation. If it does, +var1 has a value and we pass. Otherwise we fail --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1"/> + + </datamodel> + +<state id="s0"> + <onentry> + <send event="event1" idlocation="Var1"/> + </onentry> + + <transition cond="Var1" target="pass"/> + <transition target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test185.txml.json b/test/scxml-test-framework/test/w3c/test185.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test185.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test185.txml.scxml b/test/scxml-test-framework/test/w3c/test185.txml.scxml new file mode 100644 index 0000000..0d7c70f --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test185.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- we test that <send> respects the delay specification. If it does, event1 arrives before event2 + and we pass. Otherwise we fail --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="event2" delay="2s"/> + <send event="event1"/> + </onentry> + + <transition event="event1" target="s1"/> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> + <transition event="event2" target="pass"/> + <transition event="*" target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test186.txml.json b/test/scxml-test-framework/test/w3c/test186.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test186.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test186.txml.scxml b/test/scxml-test-framework/test/w3c/test186.txml.scxml new file mode 100644 index 0000000..ece1bfe --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test186.txml.scxml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- we test that <send> evals its args when it is evaluated, not when the delay interval expires and the +message is actually sent. If it does, aParam will have the value of 1 (even though var1 has been incremented +in the interval.) If var2 ends up == 1, we pass. Otherwise we fail --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="1"/> + <data id="Var2"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="event1" delay="2s"> + <param name="aParam" expr="Var1"/> + </send> + <assign location="Var1" expr="2"/> + </onentry> + + <transition event="event1" target="s1"> + <assign location="Var2" expr="_event.data.aParam"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test187.txml.json b/test/scxml-test-framework/test/w3c/test187.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test187.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test187.txml.scxml b/test/scxml-test-framework/test/w3c/test187.txml.scxml new file mode 100644 index 0000000..1704c31 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test187.txml.scxml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- we test that delayed <send> is not sent if the sending session terminates. In this case, +a subscript is invoked which sends the event childToParent delayed by 1 second, and then terminates. The +parent session, should not receive childToParent. If it does, we fail. Otherwise the +10 sec timer expires and we pass --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="10s"/> + </onentry> + <invoke type="scxml"> + <content> + <!-- exit before the delayed send can execute --> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <state id="sub0"> + <onentry> + <send event="childToParent" target="#_parent" delay="1s"/> + </onentry> + <transition target="subFinal"/> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="childToParent" target="fail"/> + <transition event="timeout" target="pass"/> +</state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test194.txml.json b/test/scxml-test-framework/test/w3c/test194.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test194.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test194.txml.scxml b/test/scxml-test-framework/test/w3c/test194.txml.scxml new file mode 100644 index 0000000..97f5261 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test194.txml.scxml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- we test that specifying an illegal target for <send> causes the event error.execution to be raised. If it does, +we succeed. Otherwise we eventually timeout and fail. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <!-- should cause an error --> + <send target="baz" event="event2"/> + <!-- this will get added to the external event queue after the error has been raised --> + <send event="timeout"/> + </onentry> + + <!-- once we've entered the state, we should check for internal events first --> + <transition event="error.execution" target="pass"/> + <transition event="*" target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test198.txml.json b/test/scxml-test-framework/test/w3c/test198.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test198.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test198.txml.scxml b/test/scxml-test-framework/test/w3c/test198.txml.scxml new file mode 100644 index 0000000..b08078f --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test198.txml.scxml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- we test that if type is not provided <send> uses the scxml event i/o processor. The only way to tell +what processor was used is to look at the origintype of the resulting event --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + +<state id="s0"> + <onentry> + <send event="event1"/> + <send event="timeout"/> + </onentry> + + + <transition event="event1" cond=" _event.origintype == 'http://www.w3.org/TR/scxml/#SCXMLEventProcessor'" target="pass"/> + <transition event="*" target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test199.txml.json b/test/scxml-test-framework/test/w3c/test199.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test199.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test199.txml.scxml b/test/scxml-test-framework/test/w3c/test199.txml.scxml new file mode 100644 index 0000000..d54e285 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test199.txml.scxml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- we test that using an invalid send type results in error.execution --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + +<state id="s0"> + <onentry> + <send type="27" event="event1"/> + <send event="timeout"/> + </onentry> + + + <transition event="error.execution" target="pass"/> + <transition event="*" target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test200.txml.json b/test/scxml-test-framework/test/w3c/test200.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test200.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test200.txml.scxml b/test/scxml-test-framework/test/w3c/test200.txml.scxml new file mode 100644 index 0000000..ad3d4a1 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test200.txml.scxml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- we test that the processor supports the scxml event i/o processor --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> + +<state id="s0"> + <onentry> + <send type="http://www.w3.org/TR/scxml/#SCXMLEventProcessor" event="event1"/> + <send event="timeout"/> + </onentry> + + + <transition event="event1" target="pass"/> + <transition event="*" target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test201.txml.json b/test/scxml-test-framework/test/w3c/test201.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test201.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test201.txml.scxml b/test/scxml-test-framework/test/w3c/test201.txml.scxml new file mode 100644 index 0000000..de0ccd7 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test201.txml.scxml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- we test that the processor supports the basic http event i/o processor. This is an optional +test since platforms are not required to support basic http event i/o --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + +<state id="s0"> + <onentry> + <send type="http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor" event="event1"/> + <send event="timeout"/> + </onentry> + + + <transition event="event1" target="pass"/> + <transition event="*" target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test205.txml.json b/test/scxml-test-framework/test/w3c/test205.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test205.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test205.txml.scxml b/test/scxml-test-framework/test/w3c/test205.txml.scxml new file mode 100644 index 0000000..8a00ad3 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test205.txml.scxml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- we test that the processor doesn't change the message. We can't test that it never does this, but +at least we can check that the event name and included data are the same as we sent. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="event1"> + <param name="aParam" expr="1"/> + </send> + <send event="timeout"/> + </onentry> + + + <transition event="event1" target="s1"> + <assign location="Var1" expr="_event.data.aParam"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test207.txml.json b/test/scxml-test-framework/test/w3c/test207.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test207.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test207.txml.scxml b/test/scxml-test-framework/test/w3c/test207.txml.scxml new file mode 100644 index 0000000..c0d31d7 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test207.txml.scxml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<!-- we test that that we can't cancel an event in another session. We invoke a child process. It notifies +us when it has generated a delayed event with sendid foo. We try to cancel foo. The child process sends us event + event success if the event is not cancelled, event fail otherwise. This doesn't test that there is absolutely no way to cancel an event +raised in another session, but the spec doesn't define any way to refer to an event in another process --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="10s"/> + </onentry> + <invoke type="scxml"> + <content> + <!-- when invoked, we raise a delayed event1 with sendid 'foo' and notify our parent. Then we wait. + If event1 occurs, the parent hasn't succeeded in canceling it and we return pass. If event2 occurs + it means event1 was canceled (because event2 is delayed longer than event1) and we return 'fail'. --> + + + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <state id="sub0"> + <onentry> + <send event="event1" id="foo" delay="3s"/> + <send event="event2" delay="5s"/> + <send target="#_parent" event="childToParent"/> + </onentry> + + <transition event="event1" target="subFinal"> + <send target="#_parent" event="pass"/> + </transition> + <transition event="*" target="subFinal"> + <send target="#_parent" event="fail"/> + </transition> + + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <state id="s01"> + <transition event="childToParent" target="s02"> + <cancel sendid="foo"/> + </transition> + </state> + + <state id="s02"> + <transition event="pass" target="pass"/> + <transition event="fail" target="fail"/> + <transition event="timeout" target="fail"/> + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test208.txml.json b/test/scxml-test-framework/test/w3c/test208.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test208.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test208.txml.scxml b/test/scxml-test-framework/test/w3c/test208.txml.scxml new file mode 100644 index 0000000..8938858 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test208.txml.scxml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- we test that cancel works. We cancel delayed event1. If cancel works, we get event2 first and pass. If +we get event1 or an error first, cancel didn't work and we fail. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send id="foo" event="event1" delay="1s"/> + <send event="event2" delay="5s"/> + <cancel sendid="foo"/> + </onentry> + + <transition event="event2" target="pass"/> + <transition event="*" target="fail"/> + + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test210.txml.json b/test/scxml-test-framework/test/w3c/test210.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test210.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test210.txml.scxml b/test/scxml-test-framework/test/w3c/test210.txml.scxml new file mode 100644 index 0000000..9d5fb5e --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test210.txml.scxml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<!-- we test that sendidexpr works with cancel. If it takes the most recent value of var1, it should cancel +delayed event1. Thus we get event2 first and pass. If we get event1 or an error first, cancel didn't work and we fail. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="'bar'"/> + </datamodel> + +<state id="s0"> + <onentry> + <send id="foo" event="event1" delay="1s"/> + <send event="event2" delay="5s"/> + <assign location="Var1" expr="'foo'"/> + <cancel sendidexpr="Var1"/> + </onentry> + + <transition event="event2" target="pass"/> + <transition event="*" target="fail"/> + + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test215.txml.json b/test/scxml-test-framework/test/w3c/test215.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test215.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test215.txml.scxml b/test/scxml-test-framework/test/w3c/test215.txml.scxml new file mode 100644 index 0000000..67b2158 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test215.txml.scxml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- we test that typexpr is evaluated at runtime. If the original value of var1 is used, the invocation +will fail (test215sub1.scxml is not of type 'foo', even if the platform supports foo as a type). If +the runtime value is used, the invocation will succeed --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> + +<datamodel> + <data id="Var1" expr="'foo'"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="5s"/> + <assign location="Var1" expr="'http://www.w3.org/TR/scxml/'"/> + </onentry> + <invoke typeexpr="Var1"> + <content> + <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. --> + <scxml initial="subFinal" datamodel="ecmascript" version="1.0"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="done.invoke" target="pass"/> + <transition event="*" target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test216.txml.json b/test/scxml-test-framework/test/w3c/test216.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test216.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test216.txml.scxml b/test/scxml-test-framework/test/w3c/test216.txml.scxml new file mode 100644 index 0000000..e14aacf --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test216.txml.scxml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- we test that srcexpr is evaluated at runtime. If the original value of var1 is used, the invocation +will fail (assuming that there is no script named 'foo'). If +the runtime value is used, the invocation will succeed --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + +<datamodel> + <data id="Var1" expr="'foo'"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="5s"/> + <assign location="Var1" expr="'file:test216sub1.scxml'"/> + </onentry> + <invoke srcexpr="Var1" type="http://www.w3.org/TR/scxml"/> + <transition event="done.invoke" target="pass"/> + <transition event="*" target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test220.txml.json b/test/scxml-test-framework/test/w3c/test220.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test220.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test220.txml.scxml b/test/scxml-test-framework/test/w3c/test220.txml.scxml new file mode 100644 index 0000000..0774ab1 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test220.txml.scxml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- we test that the scxml type is supported. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + +<state id="s0"> + <onentry> + <send event="timeout" delay="5s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. --> + <scxml initial="subFinal" version="1.0" datamodel="ecmascript"> + <final id="subFinal"/> + </scxml></content> + </invoke> + <transition event="done.invoke" target="pass"/> + <transition event="*" target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test223.txml.json b/test/scxml-test-framework/test/w3c/test223.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test223.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test223.txml.scxml b/test/scxml-test-framework/test/w3c/test223.txml.scxml new file mode 100644 index 0000000..11baf9f --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test223.txml.scxml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- we test that idlocation is supported. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/" idlocation="Var1"> + <content> + <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. --> + <scxml initial="subFinal" version="1.0" datamodel="ecmascript"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="*" target="s1"/> +</state> + +<state id="s1"> + <transition cond="Var1" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test224.txml.json b/test/scxml-test-framework/test/w3c/test224.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test224.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test224.txml.scxml b/test/scxml-test-framework/test/w3c/test224.txml.scxml new file mode 100644 index 0000000..47110d9 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test224.txml.scxml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- we test that the automatically generated id has the form stateid.platformid. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1"/> + <data id="Var2" expr="'s0.'"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/" idlocation="Var1"> + <content> + <!-- when invoked, terminate returning done.invoke. This proves that the invocation succeeded. --> + <scxml version="1.0" initial="subFinal" datamodel="ecmascript"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="*" target="s1"/> +</state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test225.txml.json b/test/scxml-test-framework/test/w3c/test225.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test225.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test225.txml.scxml b/test/scxml-test-framework/test/w3c/test225.txml.scxml new file mode 100644 index 0000000..39dcc78 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test225.txml.scxml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<!-- we test that the automatically generated id is unique, we call invoke twice and compare the ids. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1"/> + <data id="Var2"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" idlocation="Var1"> + <content> + <scxml initial="subFinal1" version="1.0" datamodel="ecmascript"> + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <invoke type="http://www.w3.org/TR/scxml/" idlocation="Var2"> + <content> + <scxml initial="subFinal2" version="1.0" datamodel="ecmascript"> + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + + <transition event="*" target="s1"/> +</state> + +<state id="s1"> + <transition cond="" target="fail"/> + <transition target="pass"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test226.txml.json b/test/scxml-test-framework/test/w3c/test226.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test226.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test226.txml.scxml b/test/scxml-test-framework/test/w3c/test226.txml.scxml new file mode 100644 index 0000000..57d6fa3 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test226.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- this is basically just a test that invoke works correctly and that you can pass data +to the invoked process. If the invoked session finds aParam==1, it exits, signalling +success. otherwise it will hang and the timeout in this doc signifies failure. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + + + <invoke type="http://www.w3.org/TR/scxml/" src="file:test226sub1.txml"> + <param name="Var1" expr="1"/> + </invoke> + + <transition event="varBound" target="pass"/> + <transition event="*" target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test228.txml.json b/test/scxml-test-framework/test/w3c/test228.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test228.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test228.txml.scxml b/test/scxml-test-framework/test/w3c/test228.txml.scxml new file mode 100644 index 0000000..7979330 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test228.txml.scxml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- test that the invokeid is included in events returned from the invoked process. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" id="foo"> + <content> + <scxml initial="subFinal" version="1.0" datamodel="ecmascript"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="done.invoke" target="s1"> + <assign location="Var1" expr="_event.invokeid"/> + </transition> + <transition event="*" target="fail"/> +</state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test229.txml.json b/test/scxml-test-framework/test/w3c/test229.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test229.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test229.txml.scxml b/test/scxml-test-framework/test/w3c/test229.txml.scxml new file mode 100644 index 0000000..6e6d5c1 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test229.txml.scxml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<!-- test that autofoward works. If the child process receives back a copy of the +childToParent event that it sends to this doc, it sends eventReceived, signalling success. (Note +that this doc is not required to process that event explicitly. It should be forwarded in any case.) Otherwise +it eventually times out and the done.invoke signals failure --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" autoforward="true"> + <content> + <!-- when invoked, send childToParent to parent. + If it is forwarded back to us, send + eventReceived to signal success and terminate. + Otherwise wait for timer to expire and terminate. --> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <state id="sub0"> + <onentry> + <send target="#_parent" event="childToParent"/> + <send event="timeout" delay="3s"/> + </onentry> + <transition event="childToParent" target="subFinal"> + <send target="#_parent" event="eventReceived"/> + </transition> + <transition event="*" target="subFinal"/> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="childToParent"/> + <transition event="eventReceived" target="pass"/> + <transition event="*" target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test230.txml.json b/test/scxml-test-framework/test/w3c/test230.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test230.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test230.txml.scxml b/test/scxml-test-framework/test/w3c/test230.txml.scxml new file mode 100644 index 0000000..182da6b --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test230.txml.scxml @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<!-- a manual test that an autofowarded event has the same fields and values as the original event. +the child process sends the parent process an event which is forwarded back to it. +Both the parent and child process print out the contents of the event. The tester +must check if they are the same and report his result. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/" autoforward="true"> + <content> + <!-- when invoked, send childToParent to parent. If it is forwarded back to us, print out its + fields and terminate. --> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <state id="sub0"> + <onentry> + <send target="#_parent" event="childToParent"/> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="childToParent" target="subFinal"> + <log label="name is " expr="_event.name"/> + <log label="type is " expr="_event.type"/> + <log label="sendid is " expr="_event.sendid"/> + <log label="origin is " expr="_event.origin"/> + <log label="origintype is " expr="_event.origintype"/> + <log label="invokeid is " expr="_event.invokeid"/> + <log label="data is " expr="_event.data"/> + </transition> + <transition event="*" target="subFinal"/> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="timeout" target="final"/> + + + <state id="s01"> + <transition event="childToParent" target="s02"> + <log label="name is " expr="_event.name"/> + <log label="type is " expr="_event.type"/> + <log label="sendid is " expr="_event.sendid"/> + <log label="origin is " expr="_event.origin"/> + <log label="origintype is " expr="_event.origintype"/> + <log label="invokeid is " expr="_event.invokeid"/> + <log label="data is " expr="_event.data"/> + </transition> + <transition event="*" target="fail"/> + </state> + + <state id="s02"> + <!-- wait till we get the done event to ensure that the child process has time to print out its results --> + <transition event="done.invoke" target="final"/> + </state> + +</state> + +<final id="final"/> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test232.txml.json b/test/scxml-test-framework/test/w3c/test232.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test232.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test232.txml.scxml b/test/scxml-test-framework/test/w3c/test232.txml.scxml new file mode 100644 index 0000000..2696fa0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test232.txml.scxml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- test that a parent process can receive multiple events from a child process --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="subFinal" version="1.0" datamodel="ecmascript"> + <final id="subFinal"> + <onentry> + <send target="#_parent" event="childToParent1"/> + <send target="#_parent" event="childToParent2"/> + </onentry> + </final> + </scxml> + </content> + </invoke> + <transition event="timeout" target="fail"/> + + + <state id="s01"> + <transition event="childToParent1" target="s02"/> + </state> + + <state id="s02"> + <transition event="childToParent2" target="s03"/> + </state> + +<state id="s03"> + <transition event="done.invoke" target="pass"/> + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test233.txml.json b/test/scxml-test-framework/test/w3c/test233.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test233.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test233.txml.scxml b/test/scxml-test-framework/test/w3c/test233.txml.scxml new file mode 100644 index 0000000..92cc8c2 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test233.txml.scxml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- test that finalize markup runs before the event is processed. The invoked process will +return 2 in _event.data.aParam, so that new value should be in force when we select +the transtitions. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="subFinal" version="1.0" datamodel="ecmascript"> + <final id="subFinal"> + <onentry> + <send target="#_parent" event="childToParent"> + <param name="aParam" expr="2"/> + </send> + </onentry> + </final> + </scxml> + </content> + <finalize> + <assign location="Var1" expr="_event.data.aParam"/> + </finalize> + </invoke> + + <transition event="childToParent" cond="" target="pass"/> + <transition event="*" target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test234.txml.json b/test/scxml-test-framework/test/w3c/test234.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test234.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test234.txml.scxml b/test/scxml-test-framework/test/w3c/test234.txml.scxml new file mode 100644 index 0000000..41cabbf --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test234.txml.scxml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- test that only finalize markup in the invoking state runs. the first invoked process will +return 2 in _event.data.aParam, while second invoked process sleeps without returning any events. +Only the first finalize should execute. So when we get to s1 var1 should have value 2 but +var2 should still be set to 1 --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="p0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="1"/> + <data id="Var2" expr="1"/> + </datamodel> +<parallel id="p0"> + <onentry> + <send event="timeout" delay="3s"/> + </onentry> + <transition event="timeout" target="fail"/> + + <state id="p01"> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml version="1.0" initial="subFinal1" datamodel="ecmascript"> + <final id="subFinal1"> + <onentry> + <send target="#_parent" event="childToParent"> + <param name="aParam" expr="2"/> + </send> + </onentry> + </final> + </scxml> + </content> + <finalize> + <assign location="Var1" expr="_event.data.aParam"/> + </finalize> + </invoke> + + <transition event="childToParent" cond="" target="s1"/> + <transition event="childToParent" target="fail"/> + </state> + + <state id="p02"> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml version="1.0" initial="sub0" datamodel="ecmascript"> + <state id="sub0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="subFinal2"/> + </state> + <final id="subFinal2"/> + </scxml> + </content> + <finalize> + <assign location="Var2" expr="_event.data.aParam"/> + </finalize> + </invoke> + </state> + +</parallel> + + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test235.txml.json b/test/scxml-test-framework/test/w3c/test235.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test235.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test235.txml.scxml b/test/scxml-test-framework/test/w3c/test235.txml.scxml new file mode 100644 index 0000000..a2809a4 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test235.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- test that done.invoke.id event has the right id. the invoked child terminates immediately +and should generate done.invoke.foo --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/" id="foo"> + <content> + <scxml initial="subFinal" version="1.0" datamodel="ecmascript"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="done.invoke.foo" target="pass"/> + <transition event="*" target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test236.txml.json b/test/scxml-test-framework/test/w3c/test236.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test236.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test236.txml.scxml b/test/scxml-test-framework/test/w3c/test236.txml.scxml new file mode 100644 index 0000000..08cdfef --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test236.txml.scxml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<!-- test that done.invoke.id event is the last event we receive. the invoked process sends childToParent +in the exit handler of its final state. We should get it before the done.invoke, and we should get no +events after the done.invoke. Hence timeout indicates success --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="subFinal" version="1.0" datamodel="ecmascript"> + <final id="subFinal"> + <onexit> + <send target="#_parent" event="childToParent"/> + </onexit> + </final> + </scxml> + </content> + </invoke> + + <transition event="childToParent" target="s1"/> + <transition event="done.invoke" target="fail"/> +</state> + +<state id="s1"> + <!-- here we should get done.invoke --> + <transition event="done.invoke" target="s2"/> + <transition event="*" target="fail"/> + </state> + +<state id="s2"> + <transition event="timeout" target="pass"/> + <transition event="*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test237.txml.json b/test/scxml-test-framework/test/w3c/test237.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test237.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test237.txml.scxml b/test/scxml-test-framework/test/w3c/test237.txml.scxml new file mode 100644 index 0000000..4bb72b0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test237.txml.scxml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<!-- test that cancelling works. invoked child sleeps for two seconds, then terminates. We +sleep for 1 sec in s0, then move to s1. This should cause the invocation to get cancelled. +If we receive done.invoke, the invocation wasn't cancelled, and we fail. If we receive no events by +the time timeout2 fires, success --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timeout1" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <!-- when invoked, sleep for 2 secs then terminate. Parent will try to cancel this session --> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <state id="sub0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="subFinal"/> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="timeout1" target="s1"/> + +</state> + +<state id="s1"> + <onentry> + <send event="timeout2" delay="2s"/> + </onentry> + <!-- here we should NOT get done.invoke --> + <transition event="done.invoke" target="fail"/> + <transition event="*" target="pass"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test239.txml.json b/test/scxml-test-framework/test/w3c/test239.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test239.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test239.txml.scxml b/test/scxml-test-framework/test/w3c/test239.txml.scxml new file mode 100644 index 0000000..e9ea3cd --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test239.txml.scxml @@ -0,0 +1,34 @@ +<?xml version="1.0"?> +<!-- test that markup can be specified both by 'src' and by <content> --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="fail"/> + + <state id="s01"> + <invoke type="http://www.w3.org/TR/scxml/" src="file:test239sub1.scxml"/> + <transition event="done.invoke" target="s02"/> + </state> + +<state id="s02"> + <invoke type="http://www.w3.org/TR/scxml/"> + <!-- identical to test239sub1.scxml. --> + <content> + <scxml version="1.0" initial="final" datamodel="ecmascript"> + <final id="final"/> + </scxml> + </content> + </invoke> + + <transition event="done.invoke" target="pass"/> + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test240.txml.json b/test/scxml-test-framework/test/w3c/test240.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test240.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test240.txml.scxml b/test/scxml-test-framework/test/w3c/test240.txml.scxml new file mode 100644 index 0000000..34dc4bf --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test240.txml.scxml @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<!-- test that datamodel values can be specified both by 'namelist' and by <param>. +invoked child will return success if its Var1 is set to 1, failure otherwise. This +test will fail schema validation because of the multiple occurences of Var1, but +should run correctly. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="fail"/> + + <state id="s01"> + <invoke type="http://www.w3.org/TR/scxml/" namelist="Var1"> + <content> + <scxml initial="sub01" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + <state id="sub01"> + <transition cond="" target="subFinal1"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal1"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <transition event="success" target="s02"/> + <transition event="failure" target="fail"/> + </state> + +<state id="s02"> + <invoke type="http://www.w3.org/TR/scxml/"> + <param name="Var1" expr="1"/> + <content> + <scxml initial="sub02" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + + <state id="sub02"> + <transition cond="" target="subFinal2"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal1"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + <transition event="success" target="pass"/> + <transition event="failure" target="fail"/> + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test241.txml.json b/test/scxml-test-framework/test/w3c/test241.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test241.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test241.txml.scxml b/test/scxml-test-framework/test/w3c/test241.txml.scxml new file mode 100644 index 0000000..c5ac9ff --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test241.txml.scxml @@ -0,0 +1,100 @@ +<?xml version="1.0"?> +<!-- The child process will return success ifits Var1 is set to 1, failure otherwise. For this test +we try passing in Var1 by param and by namelist and check that we either get two successes +or two failures. This test will fail schema validation due to multiple declarations of +Var1, but should run correctly. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="fail"/> + + <state id="s01"> + <invoke type="http://www.w3.org/TR/scxml/" namelist="Var1"> + <content> + <scxml initial="sub01" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + + <state id="sub01"> + <transition cond="" target="subFinal1"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal1"> + <send target="#_parent" event="failure"/> + </transition> + </state> + + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <transition event="success" target="s02"/> + <transition event="failure" target="s03"/> + </state> + +<state id="s02"> + <invoke type="http://www.w3.org/TR/scxml/"> + <param name="Var1" expr="1"/> + <content> + <scxml initial="sub02" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + + <state id="sub02"> + <transition cond="" target="subFinal2"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal2"> + <send target="#_parent" event="failure"/> + </transition> + </state> + + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + <!-- we got success in s01, so we need to do so here --> + <transition event="success" target="pass"/> + <transition event="failure" target="fail"/> + </state> + +<state id="s03"> + <invoke type="http://www.w3.org/TR/scxml/"> + <param name="Var1" expr="1"/> + <content> + <scxml initial="sub03" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + + <state id="sub03"> + <transition cond="" target="subFinal3"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal3"> + <send target="#_parent" event="failure"/> + </transition> + </state> + + <final id="subFinal3"/> + </scxml> + </content> + </invoke> + <!-- we got failure in s01, so we need to do so here --> + <transition event="failure" target="pass"/> + <transition event="success" target="fail"/> + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test242.txml.json b/test/scxml-test-framework/test/w3c/test242.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test242.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test242.txml.scxml b/test/scxml-test-framework/test/w3c/test242.txml.scxml new file mode 100644 index 0000000..f771751 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test242.txml.scxml @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<!-- test that markup specified by 'src' and by <content> is treated the same way. That means that +either we get done.invoke in both cases or in neither case (in which case we timeout) --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timeout1" delay="1s"/> + </onentry> + <transition event="timeout" target="fail"/> + + <invoke type="http://www.w3.org/TR/scxml/" src="file:test242sub1.scxml"/> + <transition event="done.invoke" target="s02"/> + <transition event="timeout1" target="s03"/> + </state> + +<state id="s02"> + <onentry> + <send event="timeout2" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <!-- identical to test242sub1.scxml. --> + <content> + <scxml version="1.0" initial="subFinal1" datamodel="ecmascript"> + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <!-- we got done.invoke last time, so we need it this time too --> + <transition event="done.invoke" target="pass"/> + <transition event="timeout2" target="fail"/> + </state> + +<state id="s03"> + <onentry> + <send event="timeout3" delay="1s"/> + </onentry> + <invoke type="http://www.w3.org/TR/scxml/"> + <!-- identical to test242sub1.scxml. --> + <content> + <scxml version="1.0" initial="subFinal2" datamodel="ecmascript"> + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + <!-- we got timeout last time, so we need it this time too --> + <transition event="timeout3" target="pass"/> + <transition event="done.invoke" target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test243.txml.json b/test/scxml-test-framework/test/w3c/test243.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test243.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test243.txml.scxml b/test/scxml-test-framework/test/w3c/test243.txml.scxml new file mode 100644 index 0000000..32b4c4f --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test243.txml.scxml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!-- test that datamodel values can be specified by param. +test240sub1 will return success ifits Var1 is set to 1, failure otherwise. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/"> + <param name="Var1" expr="1"/> + <content> + <scxml version="1.0" initial="sub0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + + <state id="sub0"> + <transition cond="" target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="success" target="pass"/> + <transition event="*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test244.txml.json b/test/scxml-test-framework/test/w3c/test244.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test244.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test244.txml.scxml b/test/scxml-test-framework/test/w3c/test244.txml.scxml new file mode 100644 index 0000000..2c3c186 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test244.txml.scxml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<!-- test that datamodel values can be specified by namelist. +invoked child will return success ifits Var1 is set to 1, failure otherwise. +This test will fail schema validation due to multiple occurrences of Var1, +but should run correctly. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" namelist="Var1"> + <content> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + + <state id="sub0"> + <transition cond="" target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="success" target="pass"/> + <transition event="*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test245.txml.json b/test/scxml-test-framework/test/w3c/test245.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test245.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test245.txml.scxml b/test/scxml-test-framework/test/w3c/test245.txml.scxml new file mode 100644 index 0000000..2d4b138 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test245.txml.scxml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- test that non-existent datamodel values are not set. Var2 is not defined in +invoked child's datamodel. It will will return success if its Var2 remains unbound, failure otherwise. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var2" expr="3"/> + </datamodel> + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/" namelist="Var2"> + <content> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <state id="sub0"> + <transition cond="Var2" target="subFinal"> + <send target="#_parent" event="failure"/> + </transition> + <transition target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <transition event="success" target="pass"/> + <transition event="*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test247.txml.json b/test/scxml-test-framework/test/w3c/test247.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test247.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test247.txml.scxml b/test/scxml-test-framework/test/w3c/test247.txml.scxml new file mode 100644 index 0000000..86324a8 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test247.txml.scxml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- test that we get done.invoke. timeout indicates failure --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml version="1.0" initial="subFinal" datamodel="ecmascript"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="done.invoke" target="pass"/> + <transition event="timeout" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test250.txml.json b/test/scxml-test-framework/test/w3c/test250.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test250.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test250.txml.scxml b/test/scxml-test-framework/test/w3c/test250.txml.scxml new file mode 100644 index 0000000..637afc9 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test250.txml.scxml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<!-- test that the onexit handlers run in the invoked process if it is cancelled. This has to be a +manual test, since this process won't accept any events from the child process once it has been cancelled. +Tester must examine log output from child process to determine success --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="foo"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <state id="sub0" initial="sub01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="subFinal"/> + <onexit> + <log expr="'Exiting sub0'"/> + </onexit> + <state id="sub01"> + <onexit> + <log expr="'Exiting sub01'"/> + </onexit> + </state> + </state> + <final id="subFinal"> + <onentry> + <log expr="'entering final state, invocation was not cancelled'"/> + </onentry> + </final> + </scxml> + </content> + </invoke> + + <!-- this transition will cause the invocation to be cancelled --> + <transition event="foo" target="final"/> + </state> + +<final id="final"/> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test252.txml.json b/test/scxml-test-framework/test/w3c/test252.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test252.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test252.txml.scxml b/test/scxml-test-framework/test/w3c/test252.txml.scxml new file mode 100644 index 0000000..da77d4a --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test252.txml.scxml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<!-- test that we don't process any events received from the invoked process once it is cancelled. child +process tries to send us childToParent in an onexit handler. If we get it, we fail. +timeout indicates success. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <transition event="timeout" target="pass"/> + <transition event="childToParent" target="fail"/> + <transition event="done.invoke" target="fail"/> + + <state id="s01"> + <onentry> + <send event="foo"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <state id="sub0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <transition event="timeout" target="subFinal"/> + <onexit> + <send target="#_parent" event="childToParent"/> + </onexit> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <!-- this transition will cause the invocation to be cancelled --> + <transition event="foo" target="s02"/> + </state> + + <state id="s02"/> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test253.txml.json b/test/scxml-test-framework/test/w3c/test253.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test253.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test253.txml.scxml b/test/scxml-test-framework/test/w3c/test253.txml.scxml new file mode 100644 index 0000000..56a9079 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test253.txml.scxml @@ -0,0 +1,81 @@ +<?xml version="1.0"?> +<!-- test that the scxml event processor is used in both directions. If child process uses the +scxml event i/o processor to communicate with us, send it an event. It will send back success if +this process uses the scxml processor to send the message to it, otherwise failure. For this test we allow +'scxml' as an alternative to the full url. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1"/> + </datamodel> + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <transition event="timeout" target="fail"/> + + <invoke type="scxml" id="foo"> + <content> + <!-- inform parent we're running then wait for it to send us an event. If it uses the scxml event i/o + processor to do so, return success, otherwise return failure. --> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var2"/> + </datamodel> + <state id="sub0"> + <onentry> + <send target="#_parent" event="childRunning"/> + </onentry> + + <transition event="parentToChild" target="sub1"> + <assign location="Var2" expr="_event.origintype"/> + </transition> + </state> + <state id="sub1"> + <transition cond="" target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + <transition cond="" target="subFinal"> + <send target="#_parent" event="success"/> + </transition> + <transition target="subFinal"> + <send target="#_parent" event="failure"/> + </transition> + </state> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + + <state id="s01"> + <transition event="childRunning" target="s02"> + <assign location="Var1" expr="_event.origintype"/> + </transition> + </state> + + <state id="s02"> + + <transition cond="" target="s03"> + <send target="#_foo" event="parentToChild"/> + </transition> + <transition cond="" target="s03"> + <send target="#_foo" event="parentToChild"/> + </transition> + + <transition target="fail"/> + + </state> + + + <state id="s03"> + <transition event="success" target="pass"/> + <transition event="fail" target="fail"/> + + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test276.txml.json b/test/scxml-test-framework/test/w3c/test276.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test276.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test276.txml.scxml b/test/scxml-test-framework/test/w3c/test276.txml.scxml new file mode 100644 index 0000000..2ec3f76 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test276.txml.scxml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<!-- test that values passed in from parent process override default values specified in the child, test276sub1.scxml. +The child returns event1 if var1 has value 1, event0 if it has default value 0. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + <state id="s0"> + <invoke type="scxml" src="file:test276sub1.scxml"> + <param name="Var1" expr="1"/> + </invoke> + <transition event="event1" target="pass"/> + <transition event="event0" target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test279.txml.json b/test/scxml-test-framework/test/w3c/test279.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test279.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test279.txml.scxml b/test/scxml-test-framework/test/w3c/test279.txml.scxml new file mode 100644 index 0000000..8bd751c --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test279.txml.scxml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- testing that in case of early binding variables are assigned values at init time, before + the state containing them is visited --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + + <state id="s0"> + <transition cond="" target="pass"/> + + <transition target="fail"/> + + </state> + +<state id="s1"> + <datamodel> + <data id="Var1" expr="1"/> + </datamodel> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test280.txml.json b/test/scxml-test-framework/test/w3c/test280.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test280.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test280.txml.scxml b/test/scxml-test-framework/test/w3c/test280.txml.scxml new file mode 100644 index 0000000..232592f --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test280.txml.scxml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- test late binding. var2 won't get bound until s1 is entered, so it shouldn't have a value in s0 and +accessing it should cause an error. It should get bound before the onentry code in s1 so it should be +possible access it there and assign its value to var1 --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript" binding="late"> + + <datamodel> + <data id="Var1"/> + </datamodel> + + <state id="s0"> + <transition cond="typeof Var2 === 'undefined' " target="s1"/> + <transition target="fail"/> + </state> + +<state id="s1"> + <datamodel> + <data id="Var2" expr="1"/> + </datamodel> + <onentry> + <assign location="Var1" expr="Var2"/> + </onentry> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test286.txml.json b/test/scxml-test-framework/test/w3c/test286.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test286.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test286.txml.scxml b/test/scxml-test-framework/test/w3c/test286.txml.scxml new file mode 100644 index 0000000..f07f3c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test286.txml.scxml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- test that assigment to a non-declared var causes an error. the transition on foo catches the case +where no error is raised --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + + + <state id="s0"> + <onentry> + <assign location="Var1" expr="1"/> + <raise event="foo"/> + </onentry> + + <transition event="error.execution" target="pass"/> + <transition event="*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test287.txml.json b/test/scxml-test-framework/test/w3c/test287.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test287.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test287.txml.scxml b/test/scxml-test-framework/test/w3c/test287.txml.scxml new file mode 100644 index 0000000..69173b7 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test287.txml.scxml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- a simple test that a legal value may be assigned to a valid data model location --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="ecmascript" version="1.0" initial="s0"> + +<datamodel> + <data id="Var1" expr="0"/> + </datamodel> + + <state id="s0"> + <onentry> + <assign location="Var1" expr="1"/> + </onentry> + + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test294.txml.json b/test/scxml-test-framework/test/w3c/test294.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test294.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test294.txml.scxml b/test/scxml-test-framework/test/w3c/test294.txml.scxml new file mode 100644 index 0000000..a5813de --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test294.txml.scxml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- test that a param inside donedata ends up in the data field of the done event and +that content inside donedata sets the full value of the event.data field --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + + <state id="s0" initial="s01"> + + <transition event="done.state.s0" cond="" target="s1"> + </transition> + + <transition event="done.state.s0" target="fail"> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <param name="Var1" expr="1"/> + </donedata> + </final> + </state> + + <state id="s1" initial="s11"> + + <transition event="done.state.s1" cond="_event.data === 'foo'" target="pass"> + </transition> + + <transition event="done.state.s1" target="fail"> + </transition> + + <state id="s11"> + <transition target="s12"/> + </state> + <final id="s12"> + <donedata> + <content>foo</content> + </donedata> + </final> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test298.txml.json b/test/scxml-test-framework/test/w3c/test298.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test298.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test298.txml.scxml b/test/scxml-test-framework/test/w3c/test298.txml.scxml new file mode 100644 index 0000000..e6cae92 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test298.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- refence a non-existent data model location in param in donedata and see that the right error is raised --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + + <state id="s0" initial="s01"> + <transition event="error.execution" target="pass"/> + <transition event="*" target="fail"/> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <param name="Var3" location="Var2"/> + </donedata> + </final> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test301.txml.json b/test/scxml-test-framework/test/w3c/test301.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test301.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test301.txml.scxml b/test/scxml-test-framework/test/w3c/test301.txml.scxml new file mode 100644 index 0000000..de2d5ea --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test301.txml.scxml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!-- the processor should reject this document because it can't download the script. +Therefore we fail if it runs at all. This test is valid only for datamodels that support scripting --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0"> + <script src="D:\foo"/> + + <state id="s0"> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test302.txml.json b/test/scxml-test-framework/test/w3c/test302.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test302.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test302.txml.scxml b/test/scxml-test-framework/test/w3c/test302.txml.scxml new file mode 100644 index 0000000..bf1be6e --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test302.txml.scxml @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<!-- test that a script is evaluated at load time. <conf:script> shoudl assign the value 1 to +Var1. Hence, if script is evaluated at download time, Var1 has a value in the initial state s0. +This test is valid only for datamodels that support scripting --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0"> + <script>var Var1 = 1</script> + + <state id="s0"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test303.txml.json b/test/scxml-test-framework/test/w3c/test303.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test303.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test303.txml.scxml b/test/scxml-test-framework/test/w3c/test303.txml.scxml new file mode 100644 index 0000000..2e44f18 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test303.txml.scxml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- to test that scripts are run as part of executable content, we check that it changes the value of a var at the +right point. This test is valid only for datamodels that support scripting --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0"> +<datamodel> +<data id="Var1" expr="0"/> +</datamodel> + + <state id="s0"> + <onentry> + <assign location="Var1" expr="2"/> + <script>var Var1 = 1</script> + </onentry> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test304.txml.json b/test/scxml-test-framework/test/w3c/test304.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test304.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test304.txml.scxml b/test/scxml-test-framework/test/w3c/test304.txml.scxml new file mode 100644 index 0000000..8230c82 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test304.txml.scxml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!-- test that a variable declared by a script can be accessed like any other part of the data model --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0"> + <script>var Var1 = 1</script> + + <state id="s0"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test307.txml.json b/test/scxml-test-framework/test/w3c/test307.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test307.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test307.txml.scxml b/test/scxml-test-framework/test/w3c/test307.txml.scxml new file mode 100644 index 0000000..4a38689 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test307.txml.scxml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" binding="late"> + +<!-- with binding=late, in s0 we access a variable that isn't created until we get to s1. Then in s1 +we access a non-existent substructure of a variable. We use log tags to report the values that both operations +yield, and whether there are errors. This is a manual test, since the tester must report whether the output +is the same in the two cases --> + +<state id="s0"> + <onentry> + <log label="entering s0 value of Var 1 is: " expr="Var1"/> + <raise event="foo"/> + </onentry> + <transition event="error" target="s1"> + <log label="error in state s0" expr="_event"/> + </transition> + <transition event="foo" target="s1"> + <log label="no error in s0" expr=""/> + </transition> + </state> + +<state id="s1"> + <datamodel> + <data id="Var1" expr="1"/> + </datamodel> + + <onentry> + <log label="entering s1, value of non-existent substructure of Var 1 is: " expr="Var1.bar"/> + <raise event="bar"/> + </onentry> + + <transition event="error" target="final"> + <log label="error in state s1" expr="_event"/> + </transition> + <transition event="bar" target="final"> + <log label="No error in s1" expr=""/> + </transition> + +</state> + +<final id="final"/> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test309.txml.json b/test/scxml-test-framework/test/w3c/test309.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test309.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test309.txml.scxml b/test/scxml-test-framework/test/w3c/test309.txml.scxml new file mode 100644 index 0000000..168c753 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test309.txml.scxml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- test that an expression that cannot be interpreted as a boolean is treated as false --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + +<state id="s0"> + <transition cond="return" target="fail"/> + <transition target="pass"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test310.txml.json b/test/scxml-test-framework/test/w3c/test310.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test310.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test310.txml.scxml b/test/scxml-test-framework/test/w3c/test310.txml.scxml new file mode 100644 index 0000000..d9245e8 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test310.txml.scxml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- simple test of the in() predicate --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="p"> + + + <parallel id="p"> + + <state id="s0"> + <transition cond="In('s1')" target="pass"/> + <transition target="fail"/> + </state> + + <state id="s1"/> + </parallel> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test311.txml.json b/test/scxml-test-framework/test/w3c/test311.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test311.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test311.txml.scxml b/test/scxml-test-framework/test/w3c/test311.txml.scxml new file mode 100644 index 0000000..57724f5 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test311.txml.scxml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- test that assignment to a non-existent location yields an error --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + + +<state id="s0"> + <onentry> + <assign location="Var1" expr="1"/> + </onentry> + <transition event="error.execution" target="pass"/> + <transition event=".*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test312.txml.json b/test/scxml-test-framework/test/w3c/test312.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test312.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test312.txml.scxml b/test/scxml-test-framework/test/w3c/test312.txml.scxml new file mode 100644 index 0000000..f5855be --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test312.txml.scxml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- test that assignment with an illegal expr raises an error --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign location="Var1" expr="return"/> + <raise event="foo"/> + </onentry> + <transition event="error.execution" target="pass"/> + <transition event=".*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test313.txml.json b/test/scxml-test-framework/test/w3c/test313.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test313.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test313.txml.scxml b/test/scxml-test-framework/test/w3c/test313.txml.scxml new file mode 100644 index 0000000..c697a4d --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test313.txml.scxml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- this is a manual test. The processor is allowed to reject this doc, but if it executes it with its illegal +expression, it must raise an error --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <assign location="Var1" expr="return"/> + <raise event="foo"/> + </onentry> + <transition event="error.execution" target="pass"/> + <transition event=".*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test314.txml.json b/test/scxml-test-framework/test/w3c/test314.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test314.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test314.txml.scxml b/test/scxml-test-framework/test/w3c/test314.txml.scxml new file mode 100644 index 0000000..c2e69c8 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test314.txml.scxml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- this is a manual test because the processor is allowed to reject this document. But if it executes it, +it should not raise an error until it gets to s03 and evaluates the illegal expr --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + + +<state id="s0" initial="s01"> + <transition event="error.execution" target="fail"/> + + <state id="s01"> + <transition target="s02"/> + </state> + + <state id="s02"> + <transition target="s03"/> + </state> + + <state id="s03"> + <onentry> + <assign location="Var1" expr="return"/> + <raise event="foo"/> + </onentry> + <transition event="error.execution" target="pass"/> + <transition event=".*" target="fail"/> + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test318.txml.json b/test/scxml-test-framework/test/w3c/test318.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test318.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test318.txml.scxml b/test/scxml-test-framework/test/w3c/test318.txml.scxml new file mode 100644 index 0000000..83a40a4 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test318.txml.scxml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- test that _event stays bound during the onexit and entry into the next state --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript" name="machineName"> +<datamodel> + <data id="Var1"/> + </datamodel> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" target="s1"/> + </state> + + <state id="s1"> + <onentry> + <raise event="bar"/> + <!-- _event should still be bound to 'foo' at this point --> + <assign location="Var1" expr="_event.name"/> + </onentry> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test319.txml.json b/test/scxml-test-framework/test/w3c/test319.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test319.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test319.txml.scxml b/test/scxml-test-framework/test/w3c/test319.txml.scxml new file mode 100644 index 0000000..adae97c --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test319.txml.scxml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- test that _event is not bound before any event has been raised --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0" name="machineName"> + + <state id="s0"> + <onentry> + <if cond="_event"> + <raise event="bound"/> + <else/> + <raise event="unbound"/> + </if> + </onentry> + <transition event="unbound" target="pass"/> + <transition event="bound" target="fail"/> + + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test321.txml.json b/test/scxml-test-framework/test/w3c/test321.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test321.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test321.txml.scxml b/test/scxml-test-framework/test/w3c/test321.txml.scxml new file mode 100644 index 0000000..c24a48f --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test321.txml.scxml @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<!-- test that _sessionid is bound on startup --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0" name="machineName"> +<datamodel> + <data id="Var1" expr="$_sessionid"/> + </datamodel> + + <state id="s0"> +<transition cond="Var1" target="pass"/> + <transition cond="true" target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test322.txml.json b/test/scxml-test-framework/test/w3c/test322.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test322.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test322.txml.scxml b/test/scxml-test-framework/test/w3c/test322.txml.scxml new file mode 100644 index 0000000..bde0843 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test322.txml.scxml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<!-- test that _sessionid remains bound to the same value throught the session. this means that it can't +be assigned to --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0" name="machineName"> +<datamodel> + <data id="Var1" expr="_sessionid"/> + <data id="Var2"/> + </datamodel> + + <state id="s0"> + <transition target="s1"/> + + </state> + + <state id="s1"> + <onentry> + <assign location="_sessionid" expr="'otherName'"/> + <raise event="foo"/> + </onentry> + + <transition event="error.execution" target="s2"/> + <transition event="*" target="fail"/> + </state> + + <state id="s2"> + + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test323.txml.json b/test/scxml-test-framework/test/w3c/test323.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test323.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test323.txml.scxml b/test/scxml-test-framework/test/w3c/test323.txml.scxml new file mode 100644 index 0000000..82122c6 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test323.txml.scxml @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<!-- test that _name is bound on startup --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript" name="machineName"> +<datamodel> + <data id="Var1" expr="$_name"/> + </datamodel> + + <state id="s0"> +<transition cond="Var1" target="pass"/> + <transition cond="true" target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test324.txml.json b/test/scxml-test-framework/test/w3c/test324.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test324.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test324.txml.scxml b/test/scxml-test-framework/test/w3c/test324.txml.scxml new file mode 100644 index 0000000..9162f9b --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test324.txml.scxml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- test that _name stays bound till the session ends. This means that it cannot be assigned to --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript" name="machineName"> + + + <state id="s0"> + <transition cond="_name === 'machineName'" target="s1"/> + <transition target="fail"/> + </state> + + <state id="s1"> + <onentry> + <assign location="_name" expr="'otherName'"/> + </onentry> + <transition cond="_name === 'machineName'" target="pass"/> + <transition target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test325.txml.json b/test/scxml-test-framework/test/w3c/test325.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test325.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test325.txml.scxml b/test/scxml-test-framework/test/w3c/test325.txml.scxml new file mode 100644 index 0000000..1d3b8fc --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test325.txml.scxml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- test that _ioprocessors is bound at startup. I'm not sure how to test for a set value or +how to test that the entries in it do represent I/O processors, since the set that each implementation +supports may be different. Suggestions welcome --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0" name="machineName"> +<datamodel> + <data id="Var1" expr="_ioprocessors"/> + </datamodel> + + + <state id="s0"> + <transition cond="Var1" target="pass"/> + <transition target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test326.txml.json b/test/scxml-test-framework/test/w3c/test326.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test326.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test326.txml.scxml b/test/scxml-test-framework/test/w3c/test326.txml.scxml new file mode 100644 index 0000000..a1fe3f9 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test326.txml.scxml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- test that _ioprocessors stays bound till the session ends. This means that it cannot be assigned to --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0" name="machineName"> +<datamodel> + <data id="Var1" expr="_ioprocessors"/> + <data id="Var2"/> + </datamodel> + + <state id="s0"> + <transition cond="Var1" target="s1"/> + <transition cond="true" target="fail"/> + </state> + + + <state id="s1"> + <onentry> + <assign location="_ioprocessors" expr="'otherName'"/> + <raise event="foo"/> + </onentry> + + <transition event="error.execution" target="s2"/> + <transition event="*" target="fail"/> + </state> + + <state id="s2"> + <onentry> + <assign location="Var2" expr="_ioprocessors"/> + </onentry> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test329.txml.json b/test/scxml-test-framework/test/w3c/test329.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test329.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test329.txml.scxml b/test/scxml-test-framework/test/w3c/test329.txml.scxml new file mode 100644 index 0000000..90dd692 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test329.txml.scxml @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<!-- test that none of the system variables can be modified --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript" name="machineName"> + <datamodel> + <data id="Var1"/> + <data id="Var2"/> + <data id="Var3"/> + <data id="Var4"/> + </datamodel> + + <state id="s0"> + <onentry> + <!-- get _event bound so we can use it in s1--> + <raise event="foo"/> + <assign location="Var1" expr="_sessionid"/> + <assign location="_sessionid" expr="27"/> + </onentry> + + <transition event="foo" cond="" target="s1"/> + <transition event="*" target="fail"/> + </state> + + <state id="s1"> + <onentry> + <assign location="Var2" expr="_event"/> + <assign location="_event" expr="27"/> + </onentry> + <transition cond="" target="s2"/> + <transition target="fail"/> + </state> + +<state id="s2"> + <onentry> + <assign location="Var3" expr="_name"/> + <assign location="_name" expr="27"/> + </onentry> + <transition cond="" target="s3"/> + <transition target="fail"/> + </state> + + +<state id="s3"> + <onentry> + <assign location="Var4" expr="_ioprocessors"/> + <assign location="_ioprocessors" expr="27"/> + </onentry> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test330.txml.json b/test/scxml-test-framework/test/w3c/test330.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test330.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test330.txml.scxml b/test/scxml-test-framework/test/w3c/test330.txml.scxml new file mode 100644 index 0000000..600e1a7 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test330.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- check that the required fields are present in both internal and external events --> +<scxml xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" name="machineName"> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" cond="'name' in _event && 'type' in _event && 'sendid' in _event && 'origin' in _event && 'invokeid' && 'data' in _event" target="s1"/> + <transition event="*" target="fail"/> + </state> + + <state id="s1"> + <onentry> + <send event="foo"/> + </onentry> + <transition event="foo" cond="'name' in _event && 'type' in _event && 'sendid' in _event && 'origin' in _event && 'invokeid' && 'data' in _event" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + <final xmlns="http://www.w3.org/2005/07/scxml" id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final xmlns="http://www.w3.org/2005/07/scxml" id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test331.txml.json b/test/scxml-test-framework/test/w3c/test331.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test331.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test331.txml.scxml b/test/scxml-test-framework/test/w3c/test331.txml.scxml new file mode 100644 index 0000000..8d814ea --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test331.txml.scxml @@ -0,0 +1,61 @@ +<?xml version="1.0"?> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0" name="machineName"> + +<!-- test that _event.type is set correctly for internal, platform, and external events --> +<datamodel> + <data id="Var1"/> + </datamodel> + + <state id="s0"> + <onentry> + <!-- internal event --> + <raise event="foo"/> + </onentry> + <transition event="foo" target="s1"> + <assign location="Var1" expr="_event.type"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> + <transition cond="" target="s2"/> + <transition target="fail"/> + </state> + +<state id="s2"> + <onentry> + <!-- this will generate an error, which is a platform event --> + <assign location="Var2" expr="1"/> + </onentry> + <transition event="error" target="s3"> + <assign location="Var1" expr="_event.type"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s3"> + <transition cond="" target="s4"/> + <transition target="fail"/> + </state> + + <state id="s4"> + <onentry> + <!-- external event --> + <send event="foo"/> + </onentry> + <transition event="foo" target="s5"> + <assign location="Var1" expr="_event.type"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s5"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test332.txml.json b/test/scxml-test-framework/test/w3c/test332.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test332.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test332.txml.scxml b/test/scxml-test-framework/test/w3c/test332.txml.scxml new file mode 100644 index 0000000..c3bee02 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test332.txml.scxml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- test that sendid is present in error events triggered by send errors --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" datamodel="ecmascript" name="machineName"> + <datamodel> + <data id="Var1"/> + <data id="Var2"/> + </datamodel> + + + <state id="s0"> + <onentry> + <!-- this will raise an error and also store the sendid in var1 --> + <send target="baz" event="foo" idlocation="Var1"/> + </onentry> + <transition event="error" target="s1"> + <!-- get the sendid out of the error event --> + <assign location="Var2" expr="_event.sendid"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> +<!-- make sure that the sendid in the error event matches the one generated when send executed --> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test333.txml.json b/test/scxml-test-framework/test/w3c/test333.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test333.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test333.txml.scxml b/test/scxml-test-framework/test/w3c/test333.txml.scxml new file mode 100644 index 0000000..9c30dd5 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test333.txml.scxml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- make sure sendid is blank in a non-error event --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" datamodel="ecmascript" name="machineName"> + + <state id="s0"> + <onentry> + <send event="foo"/> + </onentry> + <transition event="foo" cond="_event.sendid == null" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test335.txml.json b/test/scxml-test-framework/test/w3c/test335.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test335.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test335.txml.scxml b/test/scxml-test-framework/test/w3c/test335.txml.scxml new file mode 100644 index 0000000..1b6e7fb --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test335.txml.scxml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- test that origin field is blank for internal events --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" datamodel="ecmascript" name="machineName"> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" cond="_event.origin == null" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test336.txml.json b/test/scxml-test-framework/test/w3c/test336.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test336.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test336.txml.scxml b/test/scxml-test-framework/test/w3c/test336.txml.scxml new file mode 100644 index 0000000..0829262 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test336.txml.scxml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- test that the origin field of an external event contains a URL that lets you send back to the originator. In +this case it's the same session, so if we get bar we succeed --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0" name="machineName"> + + <state id="s0"> + <onentry> + <send event="foo"/> + </onentry> + <transition event="foo" target="s1"> + <send event="bar" targetexpr="_event.origin" typeexpr="_event.origintype"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> + <onentry> + <send event="baz"/> + </onentry> + <transition event="bar" target="pass"/> + <transition event="*" target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test337.txml.json b/test/scxml-test-framework/test/w3c/test337.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test337.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test337.txml.scxml b/test/scxml-test-framework/test/w3c/test337.txml.scxml new file mode 100644 index 0000000..bea5121 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test337.txml.scxml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- test that origintype is blank on internal events --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0" name="machineName"> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" cond="_event.origintype == null" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test338.txml.json b/test/scxml-test-framework/test/w3c/test338.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test338.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test338.txml.scxml b/test/scxml-test-framework/test/w3c/test338.txml.scxml new file mode 100644 index 0000000..429b945 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test338.txml.scxml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<!-- test that invokeid is set correctly in events received from an invoked process. timeout event catches the +case where the invoke doesn't work correctly --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1"/> + <data id="Var2"/> + </datamodel> + + <state id="s0"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + <invoke idlocation="Var1" type="http://www.w3.org/TR/scxml/"> + <content> + <scxml initial="sub0" version="1.0" datamodel="ecmascript" name="machineName"> + <final id="sub0"> + <onentry> + <send target="#_parent" event="event1"/> + </onentry> + </final> + </scxml> + </content> + </invoke> + <transition event="event1" target="s1"> + <assign location="Var2" expr="_event.invokeid"/> + </transition> + <transition event="event0" target="fail"/> + </state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test339.txml.json b/test/scxml-test-framework/test/w3c/test339.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test339.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test339.txml.scxml b/test/scxml-test-framework/test/w3c/test339.txml.scxml new file mode 100644 index 0000000..70b366c --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test339.txml.scxml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- test that invokeid is blank in an event that wasn't returned from an invoked process --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript" name="machineName"> + + <state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="foo" cond="_event.invokeid == null" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test342.txml.json b/test/scxml-test-framework/test/w3c/test342.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test342.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test342.txml.scxml b/test/scxml-test-framework/test/w3c/test342.txml.scxml new file mode 100644 index 0000000..1ce27a4 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test342.txml.scxml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- test that eventexpr works and sets the name field of the resulting event --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript" name="machineName"> + <datamodel> + <data id="Var1" expr="'foo'"/> + <data id="Var2"/> + </datamodel> + + <state id="s0"> + <onentry> + <send eventexpr="Var1"/> + </onentry> + <transition event="foo" target="s1"> + <assign location="Var2" expr="_event.name"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test343.txml.json b/test/scxml-test-framework/test/w3c/test343.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test343.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test343.txml.scxml b/test/scxml-test-framework/test/w3c/test343.txml.scxml new file mode 100644 index 0000000..68b2b6b --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test343.txml.scxml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- test that illegal <param> produces error.execution and empty event.data --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + + + <state id="s0" initial="s01"> + <!-- we should get the error before the done event --> + <transition event="error.execution" target="s1"/> + <transition event="done.state.s0" target="fail"/> + + <transition event="done.state.s0" target="fail"> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <param location="Varfoo" name="someParam"/> + </donedata> + </final> + </state> + + + <!-- if we get here, we received the error event. Now check that the done + event has empty event.data --> + + <state id="s1"> + <transition event="done.state.s0" cond="_event.data == null" target="pass"/> + <transition event="*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test344.txml.json b/test/scxml-test-framework/test/w3c/test344.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test344.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test344.txml.scxml b/test/scxml-test-framework/test/w3c/test344.txml.scxml new file mode 100644 index 0000000..c3983ae --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test344.txml.scxml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- test that a non-boolean cond expression evaluates to false and causes error.execution to be raised --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + +<state id="s0"> + <transition cond="return" target="fail"/> + <transition target="s1"/> + </state> + +<state id="s1"> + <onentry> + <raise event="foo"/> + </onentry> + <transition event="error.execution" target="pass"/> + <transition event="*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test346.txml.json b/test/scxml-test-framework/test/w3c/test346.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test346.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test346.txml.scxml b/test/scxml-test-framework/test/w3c/test346.txml.scxml new file mode 100644 index 0000000..f9c8081 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test346.txml.scxml @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<!-- test that any attempt to change the value of a system variable causes error.execution to be raised. +Event1..4 are there to catch the case where the error event is not raised. In cases where it is, we have +to dispose of eventn in the next state, hence the targetless transitions (which simply throw away the event.) --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript" name="machineName"> + + + <state id="s0"> + <onentry> + <assign location="_sessionid" expr="'otherName'"/> + <raise event="event1"/> + </onentry> + + <transition event="error.execution" target="s1"/> + <transition event="*" target="fail"/> + </state> + + <state id="s1"> + <onentry> + <assign location="_event" expr="'otherName'"/> + <raise event="event2"/> + </onentry> + <!-- throw out event1 if it's still around --> + <transition event="event1"/> + <transition event="error.execution" target="s2"/> + <!-- event1 would trigger this transition if we didn't drop it. We want this transition to have + a very general trigger to catch cases where the wrong error event was raised --> + <transition event="*" target="fail"/> + </state> + +<state id="s2"> + <onentry> + <assign location="_ioprocessors" expr="'otherName'"/> + <raise event="event3"/> + </onentry> + <transition event="event2"/> + <transition event="error.execution" target="s3"/> + <transition event="*" target="fail"/> + </state> + +<state id="s3"> + <onentry> + <assign location="_name" expr="'otherName'"/> + <raise event="event4"/> + </onentry> + <transition event="event3"/> + <transition event="error.execution" target="pass"/> + <transition event="*" target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test355.txml.json b/test/scxml-test-framework/test/w3c/test355.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test355.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test355.txml.scxml b/test/scxml-test-framework/test/w3c/test355.txml.scxml new file mode 100644 index 0000000..03d4a09 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test355.txml.scxml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!-- test that default initial state is first in document order. If we enter s0 first we succeed, if s1, failure. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="ecmascript" version="1.0"> + + +<state id="s0"> + <transition target="pass"/> +</state> + +<state id="s1"> + <transition target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test364.txml.json b/test/scxml-test-framework/test/w3c/test364.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test364.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test364.txml.scxml b/test/scxml-test-framework/test/w3c/test364.txml.scxml new file mode 100644 index 0000000..9040887 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test364.txml.scxml @@ -0,0 +1,75 @@ +<?xml version="1.0"?> +<!-- test that default initial states are entered when a compound state is entered. First we test +the 'initial' attribute, then the initial element, then default to the first child in document order. +If we get to s01111 we succeed, if any other state, failure. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="ecmascript" initial="s1" version="1.0"> + +<state id="s1" initial="s11p112 s11p122"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" target="fail"/> + <state id="s11" initial="s111"> + <state id="s111"/> + <parallel id="s11p1"> + <state id="s11p11" initial="s11p111"> + <state id="s11p111"/> + <state id="s11p112"> + <onentry> + <raise event="In-s11p112"/> + </onentry> + </state> + </state> + <state id="s11p12" initial="s11p121"> + <state id="s11p121"/> + <state id="s11p122"> + <transition event="In-s11p112" target="s2"/> + </state> + </state> + </parallel> + </state> +</state> + +<state id="s2"> + <initial> + <transition target="s21p112 s21p122"/> + </initial> + <transition event="timeout" target="fail"/> + <state id="s21" initial="s211"> + <state id="s211"/> + <parallel id="s21p1"> + <state id="s21p11" initial="s21p111"> + <state id="s21p111"/> + <state id="s21p112"> + <onentry> + <raise event="In-s21p112"/> + </onentry> + </state> + </state> + <state id="s21p12" initial="s21p121"> + <state id="s21p121"/> + <state id="s21p122"> + <transition event="In-s21p112" target="s3"/> + </state> + </state> + </parallel> + </state> +</state> + +<state id="s3"> + <transition target="fail"/> + <state id="s31"> + <state id="s311"> + <state id="s3111"> + <transition target="pass"/> + </state> + <state id="s3112"/> + <state id="s312"/> + <state id="s32"/> +</state> +</state> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test372.txml.json b/test/scxml-test-framework/test/w3c/test372.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test372.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test372.txml.scxml b/test/scxml-test-framework/test/w3c/test372.txml.scxml new file mode 100644 index 0000000..7e2a128 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test372.txml.scxml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- test that entering a final state generates done.state.parentid after executing the onentry elements. +Var1 should be set to 2 (but not 3) by the time the event is raised --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="ecmascript" version="1.0"> + +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + +<state id="s0" initial="s0final"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="done.state.s0" cond="" target="pass"/> + <transition event="*" target="fail"/> + + <final id="s0final"> + <onentry> + <assign location="Var1" expr="2"/> + </onentry> + <onexit> + <assign location="Var1" expr="3"/> + </onexit> + </final> +</state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test375.txml.json b/test/scxml-test-framework/test/w3c/test375.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test375.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test375.txml.scxml b/test/scxml-test-framework/test/w3c/test375.txml.scxml new file mode 100644 index 0000000..69a2e7f --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test375.txml.scxml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- test that onentry handlers are executed in document order. event1 should be raised before event2 --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="ecmascript" version="1.0"> + + + +<state id="s0"> + <onentry> + <raise event="event1"/> + </onentry> + <onentry> + <raise event="event2"/> + </onentry> + + <transition event="event1" target="s1"/> + <transition event="*" target="fail"/> + +</state> + +<state id="s1"> + <transition event="event2" target="pass"/> + <transition event="*" target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test376.txml.json b/test/scxml-test-framework/test/w3c/test376.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test376.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test376.txml.scxml b/test/scxml-test-framework/test/w3c/test376.txml.scxml new file mode 100644 index 0000000..8656795 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test376.txml.scxml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- test that each onentry handler is a separate block. The <send> of event1 will cause an error but + the increment to var1 should happen anyways --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + +<state id="s0"> + <onentry> + <send target="baz" event="event1"/> + </onentry> + <onentry> + <assign location="Var1" expr="Var1 + 1"/> + </onentry> + + <transition cond="" target="pass"/> + <transition target="fail"/> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test377.txml.json b/test/scxml-test-framework/test/w3c/test377.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test377.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test377.txml.scxml b/test/scxml-test-framework/test/w3c/test377.txml.scxml new file mode 100644 index 0000000..cd21f28 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test377.txml.scxml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- test that onexit handlers are executed in document order. event1 should be raised before event2 --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="ecmascript" version="1.0"> + + + +<state id="s0"> + <onexit> + <raise event="event1"/> + </onexit> + <onexit> + <raise event="event2"/> + </onexit> + + <transition target="s1"/> + </state> + + <state id="s1"> + + <transition event="event1" target="s2"/> + <transition event="*" target="fail"/> + +</state> + +<state id="s2"> + <transition event="event2" target="pass"/> + <transition event="*" target="fail"/> +</state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test378.txml.json b/test/scxml-test-framework/test/w3c/test378.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test378.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test378.txml.scxml b/test/scxml-test-framework/test/w3c/test378.txml.scxml new file mode 100644 index 0000000..4254686 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test378.txml.scxml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- test that each onexithandler is a separate block. The <send> of event1 will cause an error but + the increment to var1 should happen anyways --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="1"/> + </datamodel> + +<state id="s0"> + <onexit> + <send target="baz" event="event1"/> + </onexit> + <onexit> + <assign location="Var1" expr="Var1 + 1"/> + </onexit> + +<transition target="s1"/> +</state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test387.txml.json b/test/scxml-test-framework/test/w3c/test387.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test387.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test387.txml.scxml b/test/scxml-test-framework/test/w3c/test387.txml.scxml new file mode 100644 index 0000000..a56d7d8 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test387.txml.scxml @@ -0,0 +1,99 @@ +<?xml version="1.0"?> +<!-- test that the default history state works correctly. From initial state s3 we take a transition to s0's default +shallow history state. That should generate "enteringS011", which takes us to s4. In s4, we +transition to s1's default deep history state. We should end up in s122, generating "enteringS122". Otherwise failure.--> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s3" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + + <transition event="enteringS011" target="s4"/> + <transition event="*" target="fail"/> + + <history type="shallow" id="s0HistShallow"> + <transition target="s01"/> + </history> + <history type="deep" id="s0HistDeep"> + <transition target="s022"/> + </history> + <state id="s01" initial="s011"> + <state id="s011"> + <onentry> + <raise event="enteringS011"/> + </onentry> + </state> + <state id="s012"> + <onentry> + <raise event="enteringS012"/> + </onentry> + </state> + </state> + <state id="s02" initial="s021"> + <state id="s021"> + <onentry> + <raise event="enteringS021"/> + </onentry> + </state> + <state id="s022"> + <onentry> + <raise event="enteringS022"/> + </onentry> + </state> + </state> + +</state> + +<state id="s1" initial="s11"> + + <transition event="enteringS122" target="pass"/> + <transition event="*" target="fail"/> + + <history type="shallow" id="s1HistShallow"> + <transition target="s11"/> + </history> + <history type="deep" id="s1HistDeep"> + <transition target="s122"/> + </history> + <state id="s11" initial="s111"> + <state id="s111"> + <onentry> + <raise event="enteringS111"/> + </onentry> + </state> + <state id="s112"> + <onentry> + <raise event="enteringS112"/> + </onentry> + </state> + </state> + <state id="s12" initial="s121"> + <state id="s121"> + <onentry> + <raise event="enteringS121"/> + </onentry> + </state> + <state id="s122"> + <onentry> + <raise event="enteringS122"/> + </onentry> + </state> + </state> + +</state> + + +<state id="s3"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition target="s0HistShallow"/> +</state> + +<state id="s4"> + <transition target="s1HistDeep"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test388.txml.json b/test/scxml-test-framework/test/w3c/test388.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test388.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test388.txml.scxml b/test/scxml-test-framework/test/w3c/test388.txml.scxml new file mode 100644 index 0000000..c0c2e32 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test388.txml.scxml @@ -0,0 +1,78 @@ +<?xml version="1.0"?> +<!-- test that history states works correctly. The counter Var1 counts how many times +we have entered s0. The initial state is s012. We then transition to s1, which transitions +to s0's deep history state. entering.s012 should be raised, otherwise failure. Then we transition +to s02, which transitions to s0's shallow history state. That should have value s01, and its initial +state is s011, so we should get entering.s011, otherwise failure.--> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s012" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> + </datamodel> + +<state id="s0" initial="s01"> + <onentry> + <assign location="Var1" expr="Var1 + 1"/> + </onentry> + + <!-- the first time through, go to s1, setting a timer just in case something hangs --> + <transition event="entering.s012" cond="" target="s1"> + <send event="timeout" delay="2s"/> + </transition> + + <!-- the second time, we should get entering.s012. If so, go to s2, otherwise fail --> + <transition event="entering.s012" cond="" target="s2"/> + <transition event="entering" cond="" target="fail"/> + + <!-- the third time we should get entering-s011. If so, pass, otherwise fail --> + <transition event="entering.s011" cond="" target="pass"/> + <transition event="entering" cond="" target="fail"/> + + <!-- if we timeout, the state machine is hung somewhere, so fail --> + <transition event="timeout" target="fail"/> + + <history type="shallow" id="s0HistShallow"> + <transition target="s02"/> + </history> + <history type="deep" id="s0HistDeep"> + <transition target="s022"/> + </history> + <state id="s01" initial="s011"> + <state id="s011"> + <onentry> + <raise event="entering.s011"/> + </onentry> + </state> + <state id="s012"> + <onentry> + <raise event="entering.s012"/> + </onentry> + </state> + </state> + <state id="s02" initial="s021"> + <state id="s021"> + <onentry> + <raise event="entering.s021"/> + </onentry> + </state> + <state id="s022"> + <onentry> + <raise event="entering.s022"/> + </onentry> + </state> + </state> + +</state> + + +<state id="s1"> + <transition target="s0HistDeep"/> +</state> + +<state id="s2"> + <transition target="s0HistShallow"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test396.txml.json b/test/scxml-test-framework/test/w3c/test396.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test396.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test396.txml.scxml b/test/scxml-test-framework/test/w3c/test396.txml.scxml new file mode 100644 index 0000000..dbd6997 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test396.txml.scxml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- test that the value in _event.name matches the event name used to match against transitions --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="ecmascript" version="1.0"> + +<state id="s0"> + <onentry> + <raise event="foo"/> + </onentry> + + + <transition event="foo" cond="_event.name == 'foo'" target="pass"/> + <transition event="foo" target="fail"/> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test399.txml.json b/test/scxml-test-framework/test/w3c/test399.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test399.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test399.txml.scxml b/test/scxml-test-framework/test/w3c/test399.txml.scxml new file mode 100644 index 0000000..7ebccb1 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test399.txml.scxml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- test that the event name matching works correctly, including prefix matching and the fact +that the event attribute of transition may contain multiple event designators. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="2s"/> + </onentry> + + <!-- this will catch the failure case --> + <transition event="timeout" target="fail"/> + + <state id="s01"> + <onentry> + <raise event="foo"/> + </onentry> + <!-- test that an event can match against a transition with multiple descriptors --> + <transition event="foo bar" target="s02"/> + </state> + + <state id="s02"> + <onentry> + <raise event="bar"/> + </onentry> + <!-- test that an event can match the second descriptor as well --> + <transition event="foo bar" target="s03"/> + </state> + + <state id="s03"> + <onentry> + <raise event="foo.zoo"/> + </onentry> + <!-- test that a prefix descriptor matches --> + <transition event="foo bar" target="s04"/> + </state> + +<state id="s04"> + <onentry> + <raise event="foos"/> + </onentry> + <!-- test that only token prefixes match --> + <transition event="foo" target="fail"/> + <transition event="foos" target="s05"/> +</state> + +<state id="s05"> + <onentry> + <raise event="foo.zoo"/> + </onentry> + <!-- test that .* works at the end of a descriptor --> + <transition event="foo.*" target="s06"/> + </state> + + <state id="s06"> + <onentry> + <raise event="foo"/> + </onentry> + <!-- test that "*" works by itself --> + <transition event="*" target="pass"/> + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test401.txml.json b/test/scxml-test-framework/test/w3c/test401.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test401.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test401.txml.scxml b/test/scxml-test-framework/test/w3c/test401.txml.scxml new file mode 100644 index 0000000..697ec0e --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test401.txml.scxml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- test that errors go in the internal event queue. We send ourselves an external event foo, then perform +and operation that raises an error. Then check that the error event is processed first, even though +it was raised second --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="foo"/> + <!-- assigning to a non-existent location should raise an error --> + <assign location="Var1" expr="2"/> + </onentry> + + + <transition event="foo" target="fail"/> + <transition event="error" target="pass"/> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test402.txml.json b/test/scxml-test-framework/test/w3c/test402.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test402.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test402.txml.scxml b/test/scxml-test-framework/test/w3c/test402.txml.scxml new file mode 100644 index 0000000..8527c39 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test402.txml.scxml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- the assertion that errors are 'like any other event' is pretty broad, but we can check that they +are pulled off the internal queue in order, and that prefix matching works on them. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <!-- catch the failure case --> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" target="fail"/> + + <state id="s01"> + <onentry> + <!-- the first internal event. The error will be the second, and event2 will be the third --> + <raise event="event1"/> + <!-- assigning to a non-existent location should raise an error --> + <assign location="Var1" expr="2"/> + </onentry> + + <transition event="event1" target="s02"> + <raise event="event2"/> + </transition> + <transition event="*" target="fail"/> + </state> + +<state id="s02"> + <transition event="error" target="s03"/> + <transition event="*" target="fail"/> + </state> + +<state id="s03"> + <transition event="event2" target="pass"/> + <transition event="*" target="fail"/> + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test403a.txml.json b/test/scxml-test-framework/test/w3c/test403a.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test403a.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test403a.txml.scxml b/test/scxml-test-framework/test/w3c/test403a.txml.scxml new file mode 100644 index 0000000..a40d623 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test403a.txml.scxml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<!-- we test one part of 'optimal enablement' meaning that of all transitions that are enabled, we chose the ones +in child states over parent states, and use document order to break ties. We have +a parent state s0 with two children, s01 and s02. In s01, we test that a) if +a transition in the child matches, we don't consider matches in the parent and b) +that if two transitions match in any state, we take the first in document order. +In s02 we test that we take a transition in the parent if there is no +matching transition in the child. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <!-- catch the failure case --> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" target="fail"/> + <transition event="event1" target="fail"/> + <transition event="event2" target="pass"/> + + <state id="s01"> + <onentry> + <!-- this should be caught by the first transition in this state, taking us to S02 --> + <raise event="event1"/> + </onentry> + + <transition event="event1" target="s02"/> + <transition event="*" target="fail"/> + </state> + +<state id="s02"> + <onentry> + <!-- since the local transition has a cond that evaluates to false this should be caught by a + transition in the parent state, taking us to pass --> + <raise event="event2"/> + </onentry> + <transition event="event1" target="fail"/> + <transition event="event2" cond="false" target="fail"/> + </state> + +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test403b.txml.json b/test/scxml-test-framework/test/w3c/test403b.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test403b.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test403b.txml.scxml b/test/scxml-test-framework/test/w3c/test403b.txml.scxml new file mode 100644 index 0000000..6d694b0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test403b.txml.scxml @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<!-- we test that 'optimally enabled set' really is a set, specifically that if a transition is optimally enabled in +two different states, it is taken only once. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + +<state id="s0" initial="p0"> + <!-- this transition should never be taken because a transition in a lower state should + always be selected --> + <transition event="event1"> + <assign location="Var1" expr="Var1 + 1"/> + </transition> + + + + <parallel id="p0"> + + <onentry> + <raise event="event1"/> + <raise event="event2"/> + </onentry> + + <!-- this transition will be selected by both states p0s1 and p0s2, but should be executed only once --> + <transition event="event1"> + <assign location="Var1" expr="Var1 + 1"/> + </transition> + + <state id="p0s1"> + <transition event="event2" cond="" target="pass"/> + <transition event="event2" target="fail"/> + </state> + + <state id="p0s2"/> + +</parallel> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test403c.txml.json b/test/scxml-test-framework/test/w3c/test403c.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test403c.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test403c.txml.scxml b/test/scxml-test-framework/test/w3c/test403c.txml.scxml new file mode 100644 index 0000000..a816904 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test403c.txml.scxml @@ -0,0 +1,56 @@ +<?xml version="1.0"?> +<!-- we test 'optimally enabled set', specifically that preemption works correctly --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> + +<state id="s0" initial="p0"> + <onentry> + <raise event="event1"/> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="event2" target="fail"/> + <transition event="timeout" target="fail"/> + + <parallel id="p0"> + + <state id="p0s1"> + <transition event="event1"/> + <transition event="event2"/> + </state> + + <state id="p0s2"> + <transition event="event1" target="p0s1"> + <raise event="event2"/> + </transition> + + </state> + + <state id="p0s3"> + <!-- this transition should be blocked by the one in p0s2--> + <transition event="event1" target="fail"/> + <!-- this transition will preempt the one that p0s2 inherits + from an ancestor --> + <transition event="event2" target="s1"/> + + </state> + +<state id="p0s4"> + <!-- this transition never gets preempted, should fire twice --> + <transition event="*"> + <assign location="Var1" expr="Var1 + 1"/> + </transition> + </state> + +</parallel> +</state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test404.txml.json b/test/scxml-test-framework/test/w3c/test404.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test404.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test404.txml.scxml b/test/scxml-test-framework/test/w3c/test404.txml.scxml new file mode 100644 index 0000000..a37534a --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test404.txml.scxml @@ -0,0 +1,62 @@ +<?xml version="1.0"?> +<!-- test that states are exited in exit order (children before parents with reverse doc order used to break ties + before the executable content in the transitions. event1, event2, event3, event4 should be raised in that + order when s01p is exited --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01p"> + + + +<parallel id="s01p"> + <onexit> + <!-- this should be the 3rd event raised --> + <raise event="event3"/> + </onexit> + <transition target="s02"> + <!-- this should be the fourth event raised --> + <raise event="event4"/> + </transition> + + <state id="s01p1"> + <onexit> + <!-- this should be the second event raised --> + <raise event="event2"/> + </onexit> + </state> + + <state id="s01p2"> + <!-- this should be the first event raised --> + <onexit> + <raise event="event1"/> + </onexit> + </state> + </parallel> + + <state id="s02"> + <transition event="event1" target="s03"/> + <transition event="*" target="fail"/> + </state> + + <state id="s03"> + <transition event="event2" target="s04"/> + <transition event="*" target="fail"/> + </state> + + <state id="s04"> + <transition event="event3" target="s05"/> + <transition event="*" target="fail"/> + </state> + + <state id="s05"> + <transition event="event4" target="pass"/> + <transition event="*" target="fail"/> + </state> + + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test405.txml.json b/test/scxml-test-framework/test/w3c/test405.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test405.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test405.txml.scxml b/test/scxml-test-framework/test/w3c/test405.txml.scxml new file mode 100644 index 0000000..48275ef --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test405.txml.scxml @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<!-- test that the executable content in the transitions is executed in document order after +the states are exited. event1, event2, event3, event4 should be raised in that order when the +state machine is entered --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + +<state id="s0" initial="s01p"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" target="fail"/> + +<parallel id="s01p"> + <transition event="event1" target="s02"/> + + + <state id="s01p1" initial="s01p11"> + <state id="s01p11"> + <onexit> + <!-- this should be the second event raised --> + <raise event="event2"/> + </onexit> + <transition target="s01p12"> + <!-- this should be the third event raised --> + <raise event="event3"/> + </transition> + </state> + <state id="s01p12"/> + </state> <!-- end s01p1 --> + + <state id="s01p2" initial="s01p21"> + <state id="s01p21"> + <onexit> + <!-- this should be the first event raised --> + <raise event="event1"/> + </onexit> + <transition target="s01p22"> + <!-- this should be the fourth event raised --> + <raise event="event4"/> + </transition> + </state> + <state id="s01p22"/> + + </state> <!-- end s01p2 --> + </parallel> + + + <state id="s02"> + <transition event="event2" target="s03"/> + <transition event="*" target="fail"/> + </state> + + <state id="s03"> + <transition event="event3" target="s04"/> + <transition event="*" target="fail"/> + </state> + + + <state id="s04"> + <transition event="event4" target="pass"/> + <transition event="*" target="fail"/> + </state> + + </state> <!-- end s01 --> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test406.txml.json b/test/scxml-test-framework/test/w3c/test406.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test406.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test406.txml.scxml b/test/scxml-test-framework/test/w3c/test406.txml.scxml new file mode 100644 index 0000000..66c83fd --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test406.txml.scxml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<!-- Test that states are entered in entry order (parents before children with document order used to break ties) +after the executable content in the transition is executed. event1, event2, event3, event4 should be raised in that +order when the transition in s01 is taken --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s0" datamodel="ecmascript"> + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" target="fail"/> + + <state id="s01"> + <transition target="s0p2"> + <!-- this should be the first event raised --> + <raise event="event1"/> + </transition> + </state> + +<parallel id="s0p2"> + + <transition event="event1" target="s03"/> + + <state id="s01p21"> + <onentry> + <!-- third event --> + <raise event="event3"/> + </onentry> + </state> + + <state id="s01p22"> + <onentry> + <!-- the fourth event --> + <raise event="event4"/> + </onentry> + </state> + + <onentry> + <!-- this should be the second event raised --> + <raise event="event2"/> + </onentry> + </parallel> + + + <state id="s03"> + <transition event="event2" target="s04"/> + <transition event="*" target="fail"/> + </state> + + <state id="s04"> + <transition event="event3" target="s05"/> + <transition event="*" target="fail"/> + </state> + + + <state id="s05"> + <transition event="event4" target="pass"/> + <transition event="*" target="fail"/> + </state> + + </state> <!-- end s0 --> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test407.txml.json b/test/scxml-test-framework/test/w3c/test407.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test407.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test407.txml.scxml b/test/scxml-test-framework/test/w3c/test407.txml.scxml new file mode 100644 index 0000000..12a49b7 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test407.txml.scxml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- a simple test that onexit handlers work. var1 should be incremented when we leave s0 --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> + </datamodel> + +<state id="s0"> + <onexit> + <assign location="Var1" expr="Var1 + 1"/> + </onexit> + <transition target="s1"/> +</state> + +<state id="s1"> + <transition cond="" target="pass"/> + <transition target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test409.txml.json b/test/scxml-test-framework/test/w3c/test409.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test409.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test409.txml.scxml b/test/scxml-test-framework/test/w3c/test409.txml.scxml new file mode 100644 index 0000000..102c953 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test409.txml.scxml @@ -0,0 +1,34 @@ +<?xml version="1.0"?> +<!-- we test that states are removed from the active states list as they are exited. When s01's onexit handler +fires, s011 should not be on the active state list, so in(S011) should be false, and event1 should not +be raised. Therefore the timeout should fire to indicate success --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + + <transition event="timeout" target="pass"/> + <transition event="event1" target="fail"/> + + <state id="s01" initial="s011"> + <onexit> + <if cond="In('s011')"> + <raise event="event1"/> + </if> + </onexit> + + <state id="s011"> + <transition target="s02"/> + </state> + </state> <!-- end s01 --> + +<state id="s02"/> + +</state> <!-- end s0 --> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test411.txml.json b/test/scxml-test-framework/test/w3c/test411.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test411.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test411.txml.scxml b/test/scxml-test-framework/test/w3c/test411.txml.scxml new file mode 100644 index 0000000..9ca7405 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test411.txml.scxml @@ -0,0 +1,34 @@ +<?xml version="1.0"?> +<!-- we test that states are added to the active states list as they are entered and before onentry handlers +are executed. When s0's onentry handler fires we should not be in s01. But when s01's onentry handler +fires, we should be in s01. Therefore event1 should not fire, but event2 should. Either event1 or +timeout also indicates failure --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="1s"/> + <if cond="In('s01')"> + <raise event="event1"/> + </if> + </onentry> + + <transition event="timeout" target="fail"/> + <transition event="event1" target="fail"/> + <transition event="event2" target="pass"/> + + <state id="s01"> + <onentry> + <if cond="In('s01')"> + <raise event="event2"/> + </if> + </onentry> + </state> + +</state> <!-- end s0 --> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test412.txml.json b/test/scxml-test-framework/test/w3c/test412.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test412.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test412.txml.scxml b/test/scxml-test-framework/test/w3c/test412.txml.scxml new file mode 100644 index 0000000..c4cbed9 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test412.txml.scxml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- test that executable content in the <initial> transition executes after the onentry handler on the state +and before the onentry handler of the child states. Event1, event2, and event3 should occur in that order. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0" initial="s01"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + + <transition event="timeout" target="fail"/> + <transition event="event1" target="fail"/> + <transition event="event2" target="pass"/> + + <state id="s01"> + <onentry> + <raise event="event1"/> + </onentry> + <initial> + <transition target="s011"> + <raise event="event2"/> + </transition> + </initial> + + <state id="s011"> + <onentry> + <raise event="event3"/> + </onentry> + <transition target="s02"/> + </state> + </state> + +<state id="s02"> + <transition event="event1" target="s03"/> + <transition event="*" target="fail"/> + </state> + +<state id="s03"> + <transition event="event2" target="s04"/> + <transition event="*" target="fail"/> + </state> + +<state id="s04"> + <transition event="event3" target="pass"/> + <transition event="*" target="fail"/> + </state> + +</state> <!-- end s0 --> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test413.txml.json b/test/scxml-test-framework/test/w3c/test413.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test413.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test413.txml.scxml b/test/scxml-test-framework/test/w3c/test413.txml.scxml new file mode 100644 index 0000000..5cca2db --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test413.txml.scxml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- test that the state machine is put into the configuration specified by the initial element, without regard +to any other defaults. we should start off in s2p111 and s2p122. the atomic +states we should not enter all have immediate transitions to failure in them --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s2p112 s2p122" version="1.0" datamodel="ecmascript"> + + <state id="s1"> + <transition target="fail"/> + </state> + +<state id="s2" initial="s2p1"> + +<parallel id="s2p1"> + <!-- this transition will be triggered only if we end up in an illegal configuration where we're in + either s2p112 or s2p122, but not both of them --> + <transition target="fail"/> + + <state id="s2p11" initial="s2p111"> + <state id="s2p111"> + <transition target="fail"/> + </state> + + <state id="s2p112"> + <transition cond="In('s2p122')" target="pass"/> + </state> + + </state> <!-- end s2p11 --> + + <state id="s2p12" initial="s2p121"> + <state id="s2p121"> + <transition target="fail"/> + </state> + + <state id="s2p122"> + <transition cond="In('s2p112')" target="pass"/> + </state> + </state> + +</parallel> + +</state> <!-- end s2 --> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test416.txml.json b/test/scxml-test-framework/test/w3c/test416.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test416.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test416.txml.scxml b/test/scxml-test-framework/test/w3c/test416.txml.scxml new file mode 100644 index 0000000..e72a499 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test416.txml.scxml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- test that the done.state.id gets generated when we enter the final state of a compound state --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="ecmascript"> + + <state id="s1" initial="s11"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" target="fail"/> + + <state id="s11" initial="s111"> + <transition event="done.state.s11" target="pass"/> + <state id="s111"> + <transition target="s11final"/> + </state> + <final id="s11final"/> + </state> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test417.txml.json b/test/scxml-test-framework/test/w3c/test417.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test417.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test417.txml.scxml b/test/scxml-test-framework/test/w3c/test417.txml.scxml new file mode 100644 index 0000000..52a43f7 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test417.txml.scxml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- test that we get the done.state.id event when all of a +parallel elements children enter final states. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="ecmascript"> + + <state id="s1" initial="s1p1"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" target="fail"/> + + <parallel id="s1p1"> + <transition event="done.state.s1p1" target="pass"/> + + <state id="s1p11" initial="s1p111"> + <state id="s1p111"> + <transition target="s1p11final"/> + </state> + <final id="s1p11final"/> + </state> + + <state id="s1p12" initial="s1p121"> + <state id="s1p121"> + <transition target="s1p12final"/> + </state> + <final id="s1p12final"/> + </state> + + </parallel> +</state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test419.txml.json b/test/scxml-test-framework/test/w3c/test419.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test419.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test419.txml.scxml b/test/scxml-test-framework/test/w3c/test419.txml.scxml new file mode 100644 index 0000000..b8894c3 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test419.txml.scxml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<!-- test that eventless transitions take precedence over event-driven ones --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="ecmascript"> + + <state id="s1"> + <onentry> + <raise event="internalEvent"/> + <send event="externalEvent"/> + </onentry> + + <transition event="*" target="fail"/> + <transition target="pass"/> + +</state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test421.txml.json b/test/scxml-test-framework/test/w3c/test421.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test421.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test421.txml.scxml b/test/scxml-test-framework/test/w3c/test421.txml.scxml new file mode 100644 index 0000000..881f650 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test421.txml.scxml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- test that internal events take priority over external ones, and that the processor +keeps pulling off internal events until it finds one that triggers a transition --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="ecmascript"> + + <state id="s1" initial="s11"> + <onentry> + <send event="externalEvent"/> + <raise event="internalEvent1"/> + <raise event="internalEvent2"/> + <raise event="internalEvent3"/> + <raise event="internalEvent4"/> + </onentry> + + <transition event="externalEvent" target="fail"/> + + <state id="s11"> + <transition event="internalEvent3" target="s12"/> + </state> + + <state id="s12"> + <transition event="internalEvent4" target="pass"/> + </state> + +</state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test422.txml.json b/test/scxml-test-framework/test/w3c/test422.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test422.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test422.txml.scxml b/test/scxml-test-framework/test/w3c/test422.txml.scxml new file mode 100644 index 0000000..1f296ed --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test422.txml.scxml @@ -0,0 +1,77 @@ +<?xml version="1.0"?> +<!-- Test that at the end of a macrostep, the processor executes all invokes in states +that have been entered and not exited during the step. (The invokes are supposed to be executed +in document order, but we can test that since each invocation is separate and they may take +different amounts to time to start up.) In this case, there are three invoke statements, +in states s1, s11 and s12. Each invoked process returns an event named after its parent state. +The invokes in s1 and s12 should execute, but not the one +in s11. So we should receive invokeS1, invokeS12, but not invokeS12. Furthermore, when the timeout fires, var1 should equal 2.--> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" initial="s1" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> + </datamodel> + <state id="s1" initial="s11"> + <onentry> + <send event="timeout" delay="5s"/> + </onentry> + <transition event="invokeS1 invokeS12"> + <assign location="Var1" expr="Var1 + 1"/> + </transition> + <transition event="invokeS11" target="fail"/> + + <transition event="timeout" cond="" target="pass"/> + <transition event="timeout" target="fail"/> + <invoke> + <content> + <!-- when invoked, send 'foo' to parent, then terminate. --> + <scxml initial="sub0" version="1.0" datamodel="ecmascript"> + <state id="sub0"> + <onentry> + <send target="#_parent" event="invokeS1"/> + </onentry> + <transition target="subFinal0"/> + </state> + <final id="subFinal0"/> + </scxml> + </content> + </invoke> + + <state id="s11"> + <invoke> + <content> + <!-- when invoked, send 'foo' to parent, then terminate. --> + <scxml initial="sub1" version="1.0" datamodel="ecmascript"> + <state id="sub1"> + <onentry> + <send target="#_parent" event="invokeS11"/> + </onentry> + <transition target="subFinal1"/> + </state> + <final id="subFinal1"/> + </scxml> + </content> + </invoke> + <transition target="s12"/> + </state> + <state id="s12"> + <invoke> + <content> + <!-- when invoked, send 'foo' to parent, then terminate. --> + <scxml initial="sub2" version="1.0" datamodel="ecmascript"> + <state id="sub2"> + <onentry> + <send target="#_parent" event="invokeS12"/> + </onentry> + <transition target="subFinal2"/> + </state> + <final id="subFinal2"/> + </scxml> + </content> + </invoke> + </state> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test423.txml.json b/test/scxml-test-framework/test/w3c/test423.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test423.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test423.txml.scxml b/test/scxml-test-framework/test/w3c/test423.txml.scxml new file mode 100644 index 0000000..b0ab886 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test423.txml.scxml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- test that we keep pulling external events off the queue till we find one that matches a transition. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + + <state id="s0"> + <onentry> + <send event="externalEvent1"/> + <send event="externalEvent2" delay="1s"/> + <raise event="internalEvent"/> + </onentry> + <!-- in this state we should process only internalEvent --> + <transition event="internalEvent" target="s1"/> + <transition event="*" target="fail"/> + </state> + + <state id="s1"> + <!-- in this state we ignore externalEvent1 and wait for externalEvent2 --> + <transition event="externalEvent2" target="pass"/> + <transition event="internalEvent" target="fail"/> + </state> + + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test487.txml.json b/test/scxml-test-framework/test/w3c/test487.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test487.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test487.txml.scxml b/test/scxml-test-framework/test/w3c/test487.txml.scxml new file mode 100644 index 0000000..84ea76d --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test487.txml.scxml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<!-- test illegal assignment. error.execution should be raised. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> +<datamodel> + <data id="Var1" expr="return"/> + </datamodel> + +<state id="s0"> + <onentry> + <raise event="event"/> + </onentry> + + <transition event="error.execution" target="pass"/> + <transition event="*" target="fail"/> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test488.txml.json b/test/scxml-test-framework/test/w3c/test488.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test488.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test488.txml.scxml b/test/scxml-test-framework/test/w3c/test488.txml.scxml new file mode 100644 index 0000000..e0d919a --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test488.txml.scxml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- test that illegal expr in <param> produces error.execution and empty event.data --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + + + <state id="s0" initial="s01"> + <!-- we should get the error before the done event --> + <transition event="error.execution" target="s1"/> + <transition event="done.state.s0" target="fail"/> + + <transition event="done.state.s0" target="fail"> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <param expr="return" name="someParam"/> + </donedata> + </final> + </state> + + + <!-- if we get here, we received the error event. Now check that the done + event has empty event.data --> + + <state id="s1"> + <transition event="done.state.s0" cond="_event.data === ''" target="pass"/> + <transition event="*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test503.txml.json b/test/scxml-test-framework/test/w3c/test503.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test503.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test503.txml.scxml b/test/scxml-test-framework/test/w3c/test503.txml.scxml new file mode 100644 index 0000000..b747beb --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test503.txml.scxml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<!-- test that a targetless transition does not exit and reenter its source state --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> <!-- how often we have exited s2 --> + <data id="Var2" expr="0"/> <!-- how often the targetless transition in s2 has been executed --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition target="s2"/> + </state> + + <state id="s2"> + <onexit> + <assign location="Var1" expr="Var1 + 1"/> + </onexit> + <transition event="foo"> + <assign location="Var2" expr="Var2 + 1"/> + </transition> + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" cond="" target="s3"/> + <transition event="bar" target="fail"/> + </state> + + <state id="s3"> + <!-- make sure that s2 was exited only once --> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test504.txml.json b/test/scxml-test-framework/test/w3c/test504.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test504.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test504.txml.scxml b/test/scxml-test-framework/test/w3c/test504.txml.scxml new file mode 100644 index 0000000..e2c37b6 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test504.txml.scxml @@ -0,0 +1,77 @@ +<?xml version="1.0"?> +<!-- test that an external transition exits all states up the the LCCA --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> <!-- how often we have exited p --> + <data id="Var2" expr="0"/> <!-- how often we have exited ps1 --> + <data id="Var3" expr="0"/> <!-- how often we have exited ps2 --> + <data id="Var4" expr="0"/> <!-- how often the transition for foo has been taken --> + <data id="Var5" expr="0"/> <!-- how often we have exited s2 --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition target="p"/> + </state> + +<state id="s2"> + <onexit> + <assign location="Var5" expr="Var5 + 1"/> + </onexit> + +<parallel id="p"> + <onexit> + <assign location="Var1" expr="Var1 + 1"/> + </onexit> + <transition event="foo" target="ps1"> + <assign location="Var4" expr="Var4 + 1"/> + </transition> + + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" cond="" target="s3"/> + <transition event="bar" target="fail"/> + + <state id="ps1"> + <onexit> + <assign location="Var2" expr="Var2 + 1"/> + </onexit> + </state> + <state id="ps2"> + <onexit> + <assign location="Var3" expr="Var3 + 1"/> + </onexit> + </state> +</parallel> +</state> + +<state id="s3"> + <!-- make sure that p was exited twice --> + <transition cond="" target="s4"/> + <transition target="fail"/> + </state> + +<state id="s4"> + <!-- make sure that ps1 was exited twice --> + <transition cond="" target="s5"/> + <transition target="fail"/> + </state> + +<state id="s5"> + <!-- make sure that ps2 was exited twice --> + <transition cond="" target="s6"/> + <transition target="fail"/> + </state> + +<state id="s6"> + <!-- make sure that s1 was exited once --> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test505.txml.json b/test/scxml-test-framework/test/w3c/test505.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test505.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test505.txml.scxml b/test/scxml-test-framework/test/w3c/test505.txml.scxml new file mode 100644 index 0000000..87c63e7 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test505.txml.scxml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<!-- test that an internal transition does not exit its source state --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> <!-- how often we have exited s1 --> + <data id="Var2" expr="0"/> <!-- how often we have exited s11 --> + <data id="Var3" expr="0"/> <!-- how often the transition for foo has been taken --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <onexit> + <assign location="Var1" expr="Var1 + 1"/> + </onexit> + <transition event="foo" type="internal" target="s11"> + <assign location="Var3" expr="Var3 + 1"/> + </transition> + + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" cond="" target="s2"/> + <transition event="bar" target="fail"/> + + <state id="s11"> + <onexit> + <assign location="Var2" expr="Var2 + 1"/> + </onexit> + </state> + </state> + +<state id="s2"> + <!-- make sure that s1 was exited once --> + <transition cond="" target="s3"/> + <transition target="fail"/> + </state> + + +<state id="s3"> + <!-- make sure that s11 was exited twice --> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test506.txml.json b/test/scxml-test-framework/test/w3c/test506.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test506.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test506.txml.scxml b/test/scxml-test-framework/test/w3c/test506.txml.scxml new file mode 100644 index 0000000..39be6c9 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test506.txml.scxml @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<!-- test that an internal transition whose targets are not proper descendants of its source state +behaves like an external transition --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> <!-- how often we have exited s2 --> + <data id="Var2" expr="0"/> <!-- how often we have exited s21 --> + <data id="Var3" expr="0"/> <!-- how often the transition for foo has been taken --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition target="s2"/> + </state> + +<state id="s2" initial="s21"> + <onexit> + <assign location="Var1" expr="Var1 + 1"/> + </onexit> + <transition event="foo" type="internal" target="s2"> + <assign location="Var3" expr="Var3 + 1"/> + </transition> + + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" cond="" target="s3"/> + <transition event="bar" target="fail"/> + + <state id="s21"> + <onexit> + <assign location="Var2" expr="Var2 + 1"/> + </onexit> + </state> + +</state> + +<state id="s3"> + <!-- make sure that s2 was exited twice --> + <transition cond="" target="s4"/> + <transition target="fail"/> + </state> + +<state id="s4"> + <!-- make sure that s21 was exited twice --> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test521.txml.json b/test/scxml-test-framework/test/w3c/test521.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test521.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test521.txml.scxml b/test/scxml-test-framework/test/w3c/test521.txml.scxml new file mode 100644 index 0000000..ea55b10 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test521.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- we test that the processor raises error.communication if it cannot dispatch the event. +(To create an undispatchable event, we choose a non-existent session as target). If it raises +the error event, we succeed. Otherwise we eventually timeout and fail. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> + + +<state id="s0"> + <onentry> + <!-- should cause an error --> + <send target="#_scxml_foo" event="event2"/> + <!-- this will get added to the external event queue after the error has been raised --> + <send event="timeout"/> + </onentry> + + <!-- once we've entered the state, we should check for internal events first --> + <transition event="error.communication" target="pass"/> + <transition event="*" target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test525.txml.json b/test/scxml-test-framework/test/w3c/test525.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test525.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test525.txml.scxml b/test/scxml-test-framework/test/w3c/test525.txml.scxml new file mode 100644 index 0000000..6e627af --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test525.txml.scxml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- test that <foreach> does a shallow copy, so that modifying the array does not change +the iteration behavior. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" datamodel="ecmascript" version="1.0"> + <datamodel> + <data id="Var1"> + [1,2,3] + </data> + <data id="Var2" expr="0"/> <!-- counts the number of iterations --> + </datamodel> + +<state id="s0"> + <onentry> + <foreach item="Var3" array="Var1"> + <assign location="Var1" expr="[].concat(Var1, [4])"/> + <assign location="Var2" expr="Var2 + 1"/> + </foreach> + </onentry> + + <transition cond="" target="pass"/> + <transition target="fail"/> +</state> + + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test527.txml.json b/test/scxml-test-framework/test/w3c/test527.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test527.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test527.txml.scxml b/test/scxml-test-framework/test/w3c/test527.txml.scxml new file mode 100644 index 0000000..83dd3bf --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test527.txml.scxml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- simple test that 'expr' works with <content> --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + + + <state id="s0" initial="s01"> + + <transition event="done.state.s0" cond="_event.data === 'foo'" target="pass"> + </transition> + + <transition event="done.state.s0" target="fail"> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <content expr="'foo'"/> + </donedata> + </final> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test528.txml.json b/test/scxml-test-framework/test/w3c/test528.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test528.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test528.txml.scxml b/test/scxml-test-framework/test/w3c/test528.txml.scxml new file mode 100644 index 0000000..1b516a6 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test528.txml.scxml @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- test that illegal 'expr' produces error.execution and empty event.data --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + + + <state id="s0" initial="s01"> + <!-- we should get the error before the done event --> + <transition event="error.execution" target="s1"/> + <transition event="done.state.s0" target="fail"/> + + <transition event="done.state.s0" target="fail"> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <content expr="return"/> + </donedata> + </final> + </state> + + + <!-- if we get here, we received the error event. Now check that the done + event has empty event.data --> + + <state id="s1"> + <transition event="done.state.s0" cond="_event.data == null" target="pass"/> + <transition event="*" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test529.txml.json b/test/scxml-test-framework/test/w3c/test529.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test529.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test529.txml.scxml b/test/scxml-test-framework/test/w3c/test529.txml.scxml new file mode 100644 index 0000000..133ab93 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test529.txml.scxml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- simple test that children workn with <content> --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" version="1.0" datamodel="ecmascript" initial="s0"> + + + <state id="s0" initial="s01"> + + <transition event="done.state.s0" cond="_event.data === '21'" target="pass"> + </transition> + + <transition event="done.state.s0" target="fail"> + </transition> + + <state id="s01"> + <transition target="s02"/> + </state> + <final id="s02"> + <donedata> + <content>21</content> + </donedata> + </final> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test530.txml.json b/test/scxml-test-framework/test/w3c/test530.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test530.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test530.txml.scxml b/test/scxml-test-framework/test/w3c/test530.txml.scxml new file mode 100644 index 0000000..cade191 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test530.txml.scxml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<!-- test that <content> child is evaluated when <invoke> is. Var1 is initialized +with an integer value, then set to an scxml script in the onentry to s0. If <content> +is evaluated at the right time, we should get invoke.done, otherwise an error --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" expr="1"/> + </datamodel> + + <state id="s0"> + <onentry> + <assign location="Var1"> + <scxml version="1.0"><final/></scxml> + </assign> + <send event="timeout" delay="2s"/> + </onentry> + + <invoke type="http://www.w3.org/TR/scxml/"> + <content expr="Var1"/> + </invoke> + + <transition event="done.invoke" target="pass"/> + <transition event="*" target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + </scxml> diff --git a/test/scxml-test-framework/test/w3c/test533.txml.json b/test/scxml-test-framework/test/w3c/test533.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test533.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test533.txml.scxml b/test/scxml-test-framework/test/w3c/test533.txml.scxml new file mode 100644 index 0000000..1f2b0d7 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test533.txml.scxml @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<!-- test that an internal transition whose source state is not compound does exit its source state --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s1" version="1.0" datamodel="ecmascript"> +<datamodel> + <data id="Var1" expr="0"/> <!-- how often we have exited p --> + <data id="Var2" expr="0"/> <!-- how often we have exited ps1 --> + <data id="Var3" expr="0"/> <!-- how often we have exited ps2 --> + <data id="Var4" expr="0"/> <!-- how often the transition for foo has been taken --> + </datamodel> + + <state id="s1"> + <onentry> + <raise event="foo"/> + <raise event="bar"/> + </onentry> + <transition target="p"/> + </state> + +<parallel id="p"> + <onexit> + <assign location="Var1" expr="Var1 + 1"/> + </onexit> + <transition event="foo" type="internal" target="ps1"> + <assign location="Var4" expr="Var4 + 1"/> + </transition> + + <!-- make sure the transition on foo was actually taken --> + <transition event="bar" cond="" target="s2"/> + <transition event="bar" target="fail"/> + + <state id="ps1"> + <onexit> + <assign location="Var2" expr="Var2 + 1"/> + </onexit> + </state> + <state id="ps2"> + <onexit> + <assign location="Var3" expr="Var3 + 1"/> + </onexit> + </state> +</parallel> + +<state id="s2"> + <!-- make sure that p was exited twice --> + <transition cond="" target="s3"/> + <transition target="fail"/> + </state> + +<state id="s3"> + <!-- make sure that ps1 was exited twice --> + <transition cond="" target="s4"/> + <transition target="fail"/> + </state> + +<state id="s4"> + <!-- make sure that ps2 was exited twice --> + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test550.txml.json b/test/scxml-test-framework/test/w3c/test550.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test550.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test550.txml.scxml b/test/scxml-test-framework/test/w3c/test550.txml.scxml new file mode 100644 index 0000000..6112db6 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test550.txml.scxml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- test that expr can be used to assign a value to a var. This test uses early binding --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript" binding="early"> + + <state id="s0"> + + <transition cond="" target="pass"/> + <transition target="fail"/> + </state> + + <state id="s1"> + <datamodel> + <data id="Var1" expr="2"/> + </datamodel> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test551.txml.json b/test/scxml-test-framework/test/w3c/test551.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test551.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test551.txml.scxml b/test/scxml-test-framework/test/w3c/test551.txml.scxml new file mode 100644 index 0000000..d0bb3fc --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test551.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- test that inline content can be used to assign a value to a var. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" binding="early" datamodel="ecmascript"> + + + <state id="s0"> + + <transition cond="Var1" target="pass"/> + <transition target="fail"/> + </state> + +<state id="s1"> + <datamodel> + <data id="Var1"> + [1,2,3] + </data> + </datamodel> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test552.txml.json b/test/scxml-test-framework/test/w3c/test552.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test552.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test552.txml.scxml b/test/scxml-test-framework/test/w3c/test552.txml.scxml new file mode 100644 index 0000000..e3bf668 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test552.txml.scxml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<!-- test that src content can be used to assign a value to a var. Edit +test552.txt to have a value that's legal for the datamodel in question --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + <datamodel> + <data id="Var1" src="file:test552.txt"/> + </datamodel> + + <state id="s0"> + + <transition cond="Var1" target="pass"/> + <transition target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + + + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test553.txml.json b/test/scxml-test-framework/test/w3c/test553.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test553.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test553.txml.scxml b/test/scxml-test-framework/test/w3c/test553.txml.scxml new file mode 100644 index 0000000..6806373 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test553.txml.scxml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- we test that the processor does not dispatch the event if evaluation +of <send>'s args causes an error.. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" datamodel="ecmascript" version="1.0"> + + +<state id="s0"> + <onentry> + <!-- timeout event --> + <send event="timeout" delay="3s"/> + <!-- include a non-existing var in the namelist --> + <send event="event1" namelist="Var2"/> + </onentry> + + <!-- if we get the timeout before event1, we assume that event1 hasn't been sent + We ignore the error event here because this assertion doesn't mention it --> + <transition event="timeout" target="pass"/> + <transition event="event1" target="fail"/> + </state> + + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test554.txml.json b/test/scxml-test-framework/test/w3c/test554.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test554.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test554.txml.scxml b/test/scxml-test-framework/test/w3c/test554.txml.scxml new file mode 100644 index 0000000..48724ad --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test554.txml.scxml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- test that if the evaluation of <invoke>'s args causes an error, the +invocation is cancelled. In this test, that means that we don't get done.invoke +before the timer goes off. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s0" version="1.0" datamodel="ecmascript"> + + +<state id="s0"> + <onentry> + <send event="timer" delay="2s"/> + </onentry> + + <!-- namelist references an undeclared variable --> + <invoke type="http://www.w3.org/TR/scxml/" namelist="Var2"> + <content> + <scxml initial="subFinal" version="1.0" datamodel="ecmascript"> + <final id="subFinal"/> + </scxml> + </content> + </invoke> + <transition event="timer" target="pass"/> + <transition event="done.invoke" target="fail"/> + </state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test570.txml.json b/test/scxml-test-framework/test/w3c/test570.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test570.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test570.txml.scxml b/test/scxml-test-framework/test/w3c/test570.txml.scxml new file mode 100644 index 0000000..cbd2ce0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test570.txml.scxml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- test that we generate done.state.id when all a parallel state's children are in final states --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="p0" datamodel="ecmascript" version="1.0"> + <datamodel> + <data id="Var1" expr="0"/> + </datamodel> +<parallel id="p0"> + <onentry> + <send event="timeout" delay="2s"/> + <raise event="e1"/> + <raise event="e2"/> + </onentry> + <!-- record that we get the first done event --> + <transition event="done.state.p0s1"> + <assign location="Var1" expr="1"/> + </transition> + <!-- we should get the second done event before done.state.p0 --> + <transition event="done.state.p0s2" target="s1"/> + <transition event="timeout" target="fail"/> + + + <state id="p0s1" initial="p0s11"> + <state id="p0s11"> + <transition event="e1" target="p0s1final"/> + </state> + <final id="p0s1final"/> + </state> + + <state id="p0s2" initial="p0s21"> + <state id="p0s21"> + <transition event="e2" target="p0s2final"/> + </state> + <final id="p0s2final"/> + </state> + + </parallel> + + <state id="s1"> + <!-- if we get done.state.p0, success --> + <transition event="done.state.p0" cond="" target="pass"/> + <transition event="*" target="fail"/> + </state> + + <final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> + <final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> + +</scxml> diff --git a/test/scxml-test-framework/test/w3c/test576.txml.json b/test/scxml-test-framework/test/w3c/test576.txml.json new file mode 100644 index 0000000..2b697c0 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test576.txml.json @@ -0,0 +1,4 @@ +{ + "initialConfiguration" : ["pass"], + "events" : [] +} diff --git a/test/scxml-test-framework/test/w3c/test576.txml.scxml b/test/scxml-test-framework/test/w3c/test576.txml.scxml new file mode 100644 index 0000000..cf5d225 --- /dev/null +++ b/test/scxml-test-framework/test/w3c/test576.txml.scxml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<!-- test that the 'initial' value of scxml is respected. We set the value to deeply nested non-default parallel siblings and +test that both are entered. --> +<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:conf="http://www.w3.org/2005/scxml-conformance" initial="s11p112 s11p122" datamodel="ecmascript" version="1.0"> + + +<state id="s0"> + <transition target="fail"/> +</state> + +<state id="s1"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + <transition event="timeout" target="fail"/> + <state id="s11" initial="s111"> + <state id="s111"/> + <parallel id="s11p1"> + <state id="s11p11" initial="s11p111"> + <state id="s11p111"/> + <state id="s11p112"> + <onentry> + <raise event="In-s11p112"/> + </onentry> + </state> + </state> + <state id="s11p12" initial="s11p121"> + <state id="s11p121"/> + <state id="s11p122"> + <transition event="In-s11p112" target="pass"/> + </state> + </state> + </parallel> + </state> +</state> + +<final id="pass"><onentry><log label="Outcome" expr="'pass'"/></onentry></final> +<final id="fail"><onentry><log label="Outcome" expr="'fail'"/></onentry></final> +</scxml> diff --git a/test/src/scxml-test-framework-client.cpp b/test/src/scxml-test-framework-client.cpp index 58f1057..fefe3d9 100644 --- a/test/src/scxml-test-framework-client.cpp +++ b/test/src/scxml-test-framework-client.cpp @@ -30,10 +30,12 @@ public: TestIOProcessor() {} virtual void beforeCompletion(uscxml::Interpreter* interpreter) { - _interpreters[interpreter->getName()].second.curlReq = NULL; + onStableConfiguration(interpreter); } - virtual void afterCompletion(uscxml::Interpreter* interpreter) {} + virtual void afterCompletion(uscxml::Interpreter* interpreter) { + _interpreters[interpreter->getName()].second.curlReq = NULL; + } virtual void beforeMicroStep(uscxml::Interpreter* interpreter) {} virtual void beforeTakingTransitions(uscxml::Interpreter* interpreter, const Arabica::XPath::NodeSet<std::string>& transitions) {} @@ -112,8 +114,8 @@ public: std::cout << "---- received:" << std::endl; evhttp_request_own(request.curlReq); - std::cout << request.content << std::endl; - uscxml::Data jsonReq = uscxml::Data::fromJSON(request.content); + std::cout << request.data.compound.at("content").atom << std::endl; + uscxml::Data jsonReq = uscxml::Data::fromJSON(request.data.compound.at("content").atom); std::cout << jsonReq << std::endl; |