diff options
Diffstat (limited to 'test/src')
-rw-r--r-- | test/src/test-c-machine.cpp | 1058 | ||||
-rw-r--r-- | test/src/test-datamodel.cpp | 32 | ||||
-rw-r--r-- | test/src/test-doneevent.cpp | 113 | ||||
-rw-r--r-- | test/src/test-flat-stateid.cpp | 4 | ||||
-rw-r--r-- | test/src/test-issue-reporting.cpp | 886 | ||||
-rw-r--r-- | test/src/test-misc.cpp | 16 | ||||
-rw-r--r-- | test/src/test-promela-parser.cpp | 38 | ||||
-rw-r--r-- | test/src/test-url.cpp | 12 | ||||
-rw-r--r-- | test/src/test-w3c.cpp | 148 |
9 files changed, 1156 insertions, 1151 deletions
diff --git a/test/src/test-c-machine.cpp b/test/src/test-c-machine.cpp index ae967ad..390ca0a 100644 --- a/test/src/test-c-machine.cpp +++ b/test/src/test-c-machine.cpp @@ -40,619 +40,621 @@ using namespace uscxml; typedef struct scxml_foreach_info scxml_foreach_info; struct scxml_foreach_info { - size_t iterations; - size_t currIteration; + size_t iterations; + size_t currIteration; }; class GenCInterpreterInfo : public InterpreterInfo { public: - NameSpaceInfo getNameSpaceInfo() const { - return nsInfo; - } - const std::string& getName() { - return name; - } - const std::string& getSessionId() { - return sessionId; - } - const std::map<std::string, IOProcessor>& getIOProcessors() { - return ioProcs; - } - bool isInState(const std::string& stateId) { - for (int i = 0 ; i < SCXML_NUMBER_STATES; i++) { - if (scxml_states[i].name != NULL && IS_SET(i, ctx->config) && stateId == scxml_states[i].name) - return true; - } - return false; - } - Arabica::DOM::Document<std::string> getDocument() const { - return document; - } - const std::map<std::string, Invoker>& getInvokers() { - return invokers; - } - - NameSpaceInfo nsInfo; - std::string name; - std::string sessionId; - std::map<std::string, IOProcessor> ioProcs; - std::map<std::string, Invoker> invokers; - Arabica::DOM::Document<std::string> document; - scxml_ctx* ctx; - DataModel datamodel; - - std::map<const scxml_elem_foreach*, scxml_foreach_info*> foreachInfo; - std::deque<Event*> iq; - std::deque<Event*> eq; - - DelayedEventQueue delayQueue; - std::map<std::string, SendRequest*> sendIds; - - tthread::condition_variable monitor; - tthread::mutex mutex; + NameSpaceInfo getNameSpaceInfo() const { + return nsInfo; + } + const std::string& getName() { + return name; + } + const std::string& getSessionId() { + return sessionId; + } + const std::map<std::string, IOProcessor>& getIOProcessors() { + return ioProcs; + } + bool isInState(const std::string& stateId) { + for (int i = 0 ; i < SCXML_NUMBER_STATES; i++) { + if (scxml_states[i].name != NULL && IS_SET(i, ctx->config) && stateId == scxml_states[i].name) + return true; + } + return false; + } + Arabica::DOM::Document<std::string> getDocument() const { + return document; + } + const std::map<std::string, Invoker>& getInvokers() { + return invokers; + } + + NameSpaceInfo nsInfo; + std::string name; + std::string sessionId; + std::map<std::string, IOProcessor> ioProcs; + std::map<std::string, Invoker> invokers; + Arabica::DOM::Document<std::string> document; + scxml_ctx* ctx; + DataModel datamodel; + + std::map<const scxml_elem_foreach*, scxml_foreach_info*> foreachInfo; + std::deque<Event*> iq; + std::deque<Event*> eq; + + DelayedEventQueue delayQueue; + std::map<std::string, SendRequest*> sendIds; + + tthread::condition_variable monitor; + tthread::mutex mutex; }; int matches(const char* desc, const char* event) { - const char* dPtr = desc; - const char* ePtr = event; - while(*dPtr != 0) { - - if (*dPtr == '*' && *ePtr != 0) // something following - return true; - - // descriptor differs from event name - if (*dPtr != *ePtr) { - // move to next descriptor - while(*dPtr != ' ' && *dPtr != 0) { - dPtr++; - } - if (*dPtr == 0) - return false; - dPtr++; - ePtr = event; - } else { - // move both pointers one character - dPtr++; - ePtr++; - - } - - // descriptor is done, return match - if (((*dPtr == 0 || *dPtr == ' ') && (*ePtr == 0 || *ePtr == ' ')) || // exact match, end of string - (*dPtr == ' ' && *ePtr == '.') || (*dPtr == 0 && *ePtr == '.')) // prefix match - return true; - } - return false; + const char* dPtr = desc; + const char* ePtr = event; + while(*dPtr != 0) { + + if (*dPtr == '*' && *ePtr != 0) // something following + return true; + + // descriptor differs from event name + if (*dPtr != *ePtr) { + // move to next descriptor + while(*dPtr != ' ' && *dPtr != 0) { + dPtr++; + } + if (*dPtr == 0) + return false; + dPtr++; + ePtr = event; + } else { + // move both pointers one character + dPtr++; + ePtr++; + + } + + // descriptor is done, return match + if (((*dPtr == 0 || *dPtr == ' ') && (*ePtr == 0 || *ePtr == ' ')) || // exact match, end of string + (*dPtr == ' ' && *ePtr == '.') || (*dPtr == 0 && *ePtr == '.')) // prefix match + return true; + } + return false; } int exec_content_raise(const scxml_ctx* ctx, const char* event) { - Event* e = new Event(); - e->name = strdup(event); - - if (boost::starts_with(e->name, "error.")) { - e->eventType = Event::PLATFORM; - } else { - e->eventType = Event::INTERNAL; - } - + Event* e = new Event(); + e->name = strdup(event); + + if (boost::starts_with(e->name, "error.")) { + e->eventType = Event::PLATFORM; + } else { + e->eventType = Event::INTERNAL; + } + #ifdef SCXML_VERBOSE - printf("Raising Internal Event: %s\n", e->name.c_str()); + printf("Raising Internal Event: %s\n", e->name.c_str()); #endif - USER_DATA(ctx)->iq.push_back(e); - return SCXML_ERR_OK; + USER_DATA(ctx)->iq.push_back(e); + return SCXML_ERR_OK; } int is_true(const scxml_ctx* ctx, const char* expr) { - try { - return USER_DATA(ctx)->datamodel.evalAsBool(expr); - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - } - return false; + try { + return USER_DATA(ctx)->datamodel.evalAsBool(expr); + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + } + return false; } int is_enabled(const scxml_ctx* ctx, const scxml_transition* t, const void* e) { - Event* event = (Event*)e; - if (event == NULL) { - if (t->event == NULL) { - // spontaneous transition, null event - if (t->condition != NULL) - return is_true(ctx, t->condition); - return true; - } else { - // spontaneous transition, but real event - return false; - } - } - - // real transition, real event - if (matches(t->event, event->name.c_str())) { - if (t->condition != NULL) - return is_true(ctx, t->condition); - return true; - } - return false; + Event* event = (Event*)e; + if (event == NULL) { + if (t->event == NULL) { + // spontaneous transition, null event + if (t->condition != NULL) + return is_true(ctx, t->condition); + return true; + } else { + // spontaneous transition, but real event + return false; + } + } + + // real transition, real event + if (matches(t->event, event->name.c_str())) { + if (t->condition != NULL) + return is_true(ctx, t->condition); + return true; + } + return false; } int raise_done_event(const scxml_ctx* ctx, const scxml_state* state, const scxml_elem_donedata* donedata) { - Event* e = new Event(); - e->name = std::string("done.state.") + state->name; - - if (donedata) { - if (donedata->content != NULL) { - e->data = Data(donedata->content, Data::VERBATIM); - } else if (donedata->contentexpr != NULL) { - try { - e->data = USER_DATA(ctx)->datamodel.getStringAsData(donedata->contentexpr); - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - } - } else { - try { - const scxml_elem_param* param = donedata->params; - while (param && ELEM_PARAM_IS_SET(param)) { - Data paramValue; - if (param->expr != NULL) { - paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->expr); - } else if(param->location) { - paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->location); - } - e->params.insert(std::make_pair(param->name, paramValue)); - param++; - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - } - } - } + Event* e = new Event(); + e->name = std::string("done.state.") + state->name; + + if (donedata) { + if (donedata->content != NULL) { + e->data = Data(donedata->content, Data::VERBATIM); + } else if (donedata->contentexpr != NULL) { + try { + e->data = USER_DATA(ctx)->datamodel.getStringAsData(donedata->contentexpr); + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + } + } else { + try { + const scxml_elem_param* param = donedata->params; + while (param && ELEM_PARAM_IS_SET(param)) { + Data paramValue; + if (param->expr != NULL) { + paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->expr); + } else if(param->location) { + paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->location); + } + e->params.insert(std::make_pair(param->name, paramValue)); + param++; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + } + } + } #ifdef SCXML_VERBOSE - printf("Raising Done Event: %s\n", e->name.c_str()); + printf("Raising Done Event: %s\n", e->name.c_str()); #endif - USER_DATA(ctx)->iq.push_back(e); - return SCXML_ERR_OK; + USER_DATA(ctx)->iq.push_back(e); + return SCXML_ERR_OK; } void delayedSend(void* ctx, std::string eventName) { - tthread::lock_guard<tthread::mutex> lock(USER_DATA(ctx)->mutex); + tthread::lock_guard<tthread::mutex> lock(USER_DATA(ctx)->mutex); - SendRequest* e = USER_DATA(ctx)->sendIds[eventName]; - if (e->target == "#_internal") { - e->eventType = Event::INTERNAL; + SendRequest* e = USER_DATA(ctx)->sendIds[eventName]; + if (e->target == "#_internal") { + e->eventType = Event::INTERNAL; #ifdef SCXML_VERBOSE - printf("Pushing Internal Event: %s\n", e->name.c_str()); + printf("Pushing Internal Event: %s\n", e->name.c_str()); #endif - USER_DATA(ctx)->iq.push_back(e); - } else { - e->eventType = Event::EXTERNAL; + USER_DATA(ctx)->iq.push_back(e); + } else { + e->eventType = Event::EXTERNAL; #ifdef SCXML_VERBOSE - printf("Pushing External Event: %s\n", e->name.c_str()); + printf("Pushing External Event: %s\n", e->name.c_str()); #endif - USER_DATA(ctx)->eq.push_back(e); - } - USER_DATA(ctx)->monitor.notify_all(); + USER_DATA(ctx)->eq.push_back(e); + } + USER_DATA(ctx)->monitor.notify_all(); } int exec_content_cancel(const scxml_ctx* ctx, const char* sendid, const char* sendidexpr) { - std::string eventId; - if (sendid != NULL) { - eventId = sendid; - } else if (sendidexpr != NULL) { - eventId = USER_DATA(ctx)->datamodel.evalAsString(sendidexpr); - } - - if (eventId.length() > 0) { - USER_DATA(ctx)->delayQueue.cancelEvent(eventId); - } else { - exec_content_raise(ctx, "error.execution"); - return SCXML_ERR_EXEC_CONTENT; - } - return SCXML_ERR_OK; + std::string eventId; + if (sendid != NULL) { + eventId = sendid; + } else if (sendidexpr != NULL) { + eventId = USER_DATA(ctx)->datamodel.evalAsString(sendidexpr); + } + + if (eventId.length() > 0) { + USER_DATA(ctx)->delayQueue.cancelEvent(eventId); + } else { + exec_content_raise(ctx, "error.execution"); + return SCXML_ERR_EXEC_CONTENT; + } + return SCXML_ERR_OK; } std::string spaceNormalize(const std::string& text) { - std::stringstream content; - std::string seperator; - - size_t start = 0; - for (int i = 0; i < text.size(); i++) { - if (isspace(text[i])) { - if (i > 0 && start < i) { - content << seperator << text.substr(start, i - start); - seperator = " "; - } - while(isspace(text[++i])); // skip whitespaces - start = i; - } else if (i + 1 == text.size()) { - content << seperator << text.substr(start, i + 1 - start); - } - } - return content.str(); + std::stringstream content; + std::string seperator; + + size_t start = 0; + for (int i = 0; i < text.size(); i++) { + if (isspace(text[i])) { + if (i > 0 && start < i) { + content << seperator << text.substr(start, i - start); + seperator = " "; + } + while(isspace(text[++i])); // skip whitespaces + start = i; + } else if (i + 1 == text.size()) { + content << seperator << text.substr(start, i + 1 - start); + } + } + return content.str(); } int exec_content_send(const scxml_ctx* ctx, const scxml_elem_send* send) { - SendRequest* e = new SendRequest(); - - std::string target; - if (send->target != NULL) { - e->target = send->target; - } else if (send->targetexpr != NULL) { - e->target = USER_DATA(ctx)->datamodel.evalAsString(send->targetexpr); - } else { - e->target = "#_external"; - } - - if (e->target.size() > 0 && (e->target[0] != '#' || e->target[1] != '_')) { - delete e; - exec_content_raise(ctx, "error.execution"); - return SCXML_ERR_INVALID_TARGET; - } - - e->origintype = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; - e->origin = e->target; - - try { - if (send->type != NULL) { - e->type = send->type; - } else if (send->typeexpr != NULL) { - e->type = USER_DATA(ctx)->datamodel.evalAsString(send->typeexpr); - } else { - e->type = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - - // only one somewhat supported - if (e->type != "http://www.w3.org/TR/scxml/#SCXMLEventProcessor") { - delete e; - exec_content_raise(ctx, "error.execution"); - return SCXML_ERR_INVALID_TARGET; - } - - e->origintype = e->type; - - if (send->eventexpr != NULL) { - e->name = USER_DATA(ctx)->datamodel.evalAsString(send->eventexpr); - } else { - e->name = strdup(send->event); - } - - try { - const scxml_elem_param* param = send->params; - while (param && ELEM_PARAM_IS_SET(param)) { - Data paramValue; - if (param->expr != NULL) { - paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->expr); - } else if(param->location) { - paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->location); - } - e->params.insert(std::make_pair(param->name, paramValue)); - param++; - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - - try { - if (send->namelist != NULL) { - const char* bPtr = &send->namelist[0]; - const char* ePtr = bPtr; - while(*ePtr != '\0') { - ePtr++; - if (*ePtr == ' ' || *ePtr == '\0') { - std::string key(bPtr, ePtr - bPtr); - e->params.insert(std::make_pair(key, USER_DATA(ctx)->datamodel.getStringAsData(key))); - if (*ePtr == '\0') - break; - bPtr = ++ePtr; - } - } - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - - if (send->content != NULL) { - // will it parse as json? - Data d = Data::fromJSON(send->content); - if (!d.empty()) { - e->data = d; - } else { - e->data = Data(spaceNormalize(send->content), Data::VERBATIM); - } - } - - const char* sendid = NULL; - if (send->id != NULL) { - sendid = send->id; - e->sendid = sendid; - } else { - sendid = strdup(UUID::getUUID().c_str()); - if (send->idlocation != NULL) { - USER_DATA(ctx)->datamodel.assign(send->idlocation, Data(sendid, Data::VERBATIM)); - } else { - e->hideSendId = true; - } - } - - - size_t delayMs = 0; - std::string delay; - if (send->delayexpr != NULL) { - delay = USER_DATA(ctx)->datamodel.evalAsString(send->delayexpr); - } else if (send->delay != NULL) { - delay = send->delay; - } - if (delay.size() > 0) { - boost::trim(delay); - - NumAttr delayAttr(delay); - if (iequals(delayAttr.unit, "ms")) { - delayMs = strTo<uint32_t>(delayAttr.value); - } else if (iequals(delayAttr.unit, "s")) { - delayMs = strTo<double>(delayAttr.value) * 1000; - } else if (delayAttr.unit.length() == 0) { // unit less delay is interpreted as milliseconds - delayMs = strTo<uint32_t>(delayAttr.value); - } else { - std::cerr << "Cannot make sense of delay value " << delay << ": does not end in 's' or 'ms'"; - } - } - - USER_DATA(ctx)->sendIds[sendid] = e; - if (delayMs > 0) { - USER_DATA(ctx)->delayQueue.addEvent(sendid, delayedSend, delayMs, (void*)ctx); - } else { - delayedSend((void*)ctx, sendid); - } - - return SCXML_ERR_OK; + SendRequest* e = new SendRequest(); + + std::string target; + if (send->target != NULL) { + e->target = send->target; + } else if (send->targetexpr != NULL) { + e->target = USER_DATA(ctx)->datamodel.evalAsString(send->targetexpr); + } else { + e->target = "#_external"; + } + + if (e->target.size() > 0 && (e->target[0] != '#' || e->target[1] != '_')) { + delete e; + exec_content_raise(ctx, "error.execution"); + return SCXML_ERR_INVALID_TARGET; + } + + e->origintype = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; + e->origin = e->target; + + try { + if (send->type != NULL) { + e->type = send->type; + } else if (send->typeexpr != NULL) { + e->type = USER_DATA(ctx)->datamodel.evalAsString(send->typeexpr); + } else { + e->type = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + + // only one somewhat supported + if (e->type != "http://www.w3.org/TR/scxml/#SCXMLEventProcessor") { + delete e; + exec_content_raise(ctx, "error.execution"); + return SCXML_ERR_INVALID_TARGET; + } + + e->origintype = e->type; + + if (send->eventexpr != NULL) { + e->name = USER_DATA(ctx)->datamodel.evalAsString(send->eventexpr); + } else { + e->name = strdup(send->event); + } + + try { + const scxml_elem_param* param = send->params; + while (param && ELEM_PARAM_IS_SET(param)) { + Data paramValue; + if (param->expr != NULL) { + paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->expr); + } else if(param->location) { + paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->location); + } + e->params.insert(std::make_pair(param->name, paramValue)); + param++; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + + try { + if (send->namelist != NULL) { + const char* bPtr = &send->namelist[0]; + const char* ePtr = bPtr; + while(*ePtr != '\0') { + ePtr++; + if (*ePtr == ' ' || *ePtr == '\0') { + std::string key(bPtr, ePtr - bPtr); + e->params.insert(std::make_pair(key, USER_DATA(ctx)->datamodel.getStringAsData(key))); + if (*ePtr == '\0') + break; + bPtr = ++ePtr; + } + } + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + + if (send->content != NULL) { + // will it parse as json? + Data d = Data::fromJSON(send->content); + if (!d.empty()) { + e->data = d; + } else { + e->data = Data(spaceNormalize(send->content), Data::VERBATIM); + } + } + + const char* sendid = NULL; + if (send->id != NULL) { + sendid = send->id; + e->sendid = sendid; + } else { + sendid = strdup(UUID::getUUID().c_str()); + if (send->idlocation != NULL) { + USER_DATA(ctx)->datamodel.assign(send->idlocation, Data(sendid, Data::VERBATIM)); + } else { + e->hideSendId = true; + } + } + + + size_t delayMs = 0; + std::string delay; + if (send->delayexpr != NULL) { + delay = USER_DATA(ctx)->datamodel.evalAsString(send->delayexpr); + } else if (send->delay != NULL) { + delay = send->delay; + } + if (delay.size() > 0) { + boost::trim(delay); + + NumAttr delayAttr(delay); + if (iequals(delayAttr.unit, "ms")) { + delayMs = strTo<uint32_t>(delayAttr.value); + } else if (iequals(delayAttr.unit, "s")) { + delayMs = strTo<double>(delayAttr.value) * 1000; + } else if (delayAttr.unit.length() == 0) { // unit less delay is interpreted as milliseconds + delayMs = strTo<uint32_t>(delayAttr.value); + } else { + std::cerr << "Cannot make sense of delay value " << delay << ": does not end in 's' or 'ms'"; + } + } + + USER_DATA(ctx)->sendIds[sendid] = e; + if (delayMs > 0) { + USER_DATA(ctx)->delayQueue.addEvent(sendid, delayedSend, delayMs, (void*)ctx); + } else { + delayedSend((void*)ctx, sendid); + } + + return SCXML_ERR_OK; } int exec_content_init(const scxml_ctx* ctx, const scxml_elem_data* data) { - while(ELEM_DATA_IS_SET(data)) { - Data d; - if (data->expr != NULL) { - d = Data(data->expr, Data::INTERPRETED); - } else if (data->content != NULL) { - d = Data(data->content, Data::INTERPRETED); - } else { - d = Data("undefined", Data::INTERPRETED); - } - try { - USER_DATA(ctx)->datamodel.init(data->id, d); - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - } - data++; - } - return SCXML_ERR_OK; + while(ELEM_DATA_IS_SET(data)) { + Data d; + if (data->expr != NULL) { + d = Data(data->expr, Data::INTERPRETED); + } else if (data->content != NULL) { + d = Data(data->content, Data::INTERPRETED); + } else { + d = Data("undefined", Data::INTERPRETED); + } + try { + USER_DATA(ctx)->datamodel.init(data->id, d); + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + } + data++; + } + return SCXML_ERR_OK; } int exec_content_assign(const scxml_ctx* ctx, const char* location, const char* expr) { - std::string key = location; - if (key == "_sessionid" || key == "_name" || key == "_ioprocessors" || key == "_invokers" || key == "_event") { - exec_content_raise(ctx, "error.execution"); - return SCXML_ERR_EXEC_CONTENT; - } - - try { - Data d(expr, Data::INTERPRETED); - USER_DATA(ctx)->datamodel.assign(key, d); - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - return SCXML_ERR_OK; + std::string key = location; + if (key == "_sessionid" || key == "_name" || key == "_ioprocessors" || key == "_invokers" || key == "_event") { + exec_content_raise(ctx, "error.execution"); + return SCXML_ERR_EXEC_CONTENT; + } + + try { + Data d(expr, Data::INTERPRETED); + USER_DATA(ctx)->datamodel.assign(key, d); + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + return SCXML_ERR_OK; } int exec_content_foreach_init(const scxml_ctx* ctx, const scxml_elem_foreach* foreach) { - try { - scxml_foreach_info* feInfo = (scxml_foreach_info*)malloc(sizeof(scxml_foreach_info)); - USER_DATA(ctx)->foreachInfo[foreach] = feInfo; - - feInfo->iterations = USER_DATA(ctx)->datamodel.getLength(foreach->array); - feInfo->currIteration = 0; - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - return SCXML_ERR_OK; + try { + scxml_foreach_info* feInfo = (scxml_foreach_info*)malloc(sizeof(scxml_foreach_info)); + USER_DATA(ctx)->foreachInfo[foreach] = feInfo; + + feInfo->iterations = USER_DATA(ctx)->datamodel.getLength(foreach->array); + feInfo->currIteration = 0; + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + return SCXML_ERR_OK; } int exec_content_foreach_next(const scxml_ctx* ctx, const scxml_elem_foreach* foreach) { - try { - scxml_foreach_info* feInfo = USER_DATA(ctx)->foreachInfo[foreach]; - if (feInfo->currIteration < feInfo->iterations) { - USER_DATA(ctx)->datamodel.setForeach((foreach->item != NULL ? foreach->item : ""), - (foreach->array != NULL ? foreach->array : ""), - (foreach->index != NULL ? foreach->index : ""), - feInfo->currIteration); - feInfo->currIteration++; - return SCXML_ERR_OK; - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - free(USER_DATA(ctx)->foreachInfo[foreach]); - USER_DATA(ctx)->foreachInfo.erase(foreach); - return SCXML_ERR_EXEC_CONTENT; - } - return SCXML_ERR_FOREACH_DONE; + try { + scxml_foreach_info* feInfo = USER_DATA(ctx)->foreachInfo[foreach]; + if (feInfo->currIteration < feInfo->iterations) { + USER_DATA(ctx)->datamodel.setForeach((foreach->item != NULL ? foreach->item : ""), + (foreach->array != NULL ? foreach->array : ""), + (foreach->index != NULL ? foreach->index : ""), + feInfo->currIteration); + feInfo->currIteration++; + return SCXML_ERR_OK; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + free(USER_DATA(ctx)->foreachInfo[foreach]); + USER_DATA(ctx)->foreachInfo.erase(foreach); + return SCXML_ERR_EXEC_CONTENT; + } + return SCXML_ERR_FOREACH_DONE; } int exec_content_foreach_done(const scxml_ctx* ctx, const scxml_elem_foreach* foreach) { - free(USER_DATA(ctx)->foreachInfo[foreach]); - USER_DATA(ctx)->foreachInfo.erase(foreach); - return SCXML_ERR_OK; + free(USER_DATA(ctx)->foreachInfo[foreach]); + USER_DATA(ctx)->foreachInfo.erase(foreach); + return SCXML_ERR_OK; } int exec_content_log(const scxml_ctx* ctx, const char* label, const char* expr) { - try { - if (label != 0) { + try { + if (label != 0) { // printf("%s: %s\n", label, USER_DATA(ctx)->datamodel.evalAsString(expr).c_str()); - } else { + } else { // printf("%s\n", USER_DATA(ctx)->datamodel.evalAsString(expr).c_str()); - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - - return SCXML_ERR_OK; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + + return SCXML_ERR_OK; } int exec_content_script(const scxml_ctx* ctx, const char* src, const char* content) { - if (content != NULL) { - USER_DATA(ctx)->datamodel.eval(Arabica::DOM::Element<std::string>(), content); - } else if (src != NULL) { - return SCXML_ERR_UNSUPPORTED; - } - return SCXML_ERR_OK; + if (content != NULL) { + USER_DATA(ctx)->datamodel.eval(Arabica::DOM::Element<std::string>(), content); + } else if (src != NULL) { + return SCXML_ERR_UNSUPPORTED; + } + return SCXML_ERR_OK; } void* dequeue_external(const scxml_ctx* ctx) { - tthread::lock_guard<tthread::mutex> lock(USER_DATA(ctx)->mutex); - while (USER_DATA(ctx)->eq.size() == 0) { - USER_DATA(ctx)->monitor.wait(USER_DATA(ctx)->mutex); - } - Event* e = USER_DATA(ctx)->eq.front(); - USER_DATA(ctx)->eq.pop_front(); - USER_DATA(ctx)->datamodel.setEvent(*e); + tthread::lock_guard<tthread::mutex> lock(USER_DATA(ctx)->mutex); + while (USER_DATA(ctx)->eq.size() == 0) { + USER_DATA(ctx)->monitor.wait(USER_DATA(ctx)->mutex); + } + Event* e = USER_DATA(ctx)->eq.front(); + USER_DATA(ctx)->eq.pop_front(); + USER_DATA(ctx)->datamodel.setEvent(*e); #ifdef SCXML_VERBOSE - printf("Popping External Event: %s\n", e->name.c_str()); + printf("Popping External Event: %s\n", e->name.c_str()); #endif - return e; + return e; } void* dequeue_internal(const scxml_ctx* ctx) { - if (USER_DATA(ctx)->iq.size() == 0) - return NULL; - Event* e = USER_DATA(ctx)->iq.front(); - USER_DATA(ctx)->iq.pop_front(); - USER_DATA(ctx)->datamodel.setEvent(*e); + if (USER_DATA(ctx)->iq.size() == 0) + return NULL; + Event* e = USER_DATA(ctx)->iq.front(); + USER_DATA(ctx)->iq.pop_front(); + USER_DATA(ctx)->datamodel.setEvent(*e); #ifdef SCXML_VERBOSE - printf("Popping Internal Event: %s\n", e->name.c_str()); + printf("Popping Internal Event: %s\n", e->name.c_str()); #endif - return e; + return e; } int main(int argc, char** argv) { - + #ifdef APPLE - mach_timebase_info_data_t timebase_info; - mach_timebase_info(&timebase_info); - - const uint64_t NANOS_PER_MSEC = 1000000ULL; - double clock2abs = ((double)timebase_info.denom / (double)timebase_info.numer) * NANOS_PER_MSEC; - - thread_time_constraint_policy_data_t policy; - policy.period = 0; - policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work - policy.constraint = (uint32_t)(10 * clock2abs); - policy.preemptible = FALSE; - - int kr = thread_policy_set(pthread_mach_thread_np(pthread_self()), - THREAD_TIME_CONSTRAINT_POLICY, - (thread_policy_t)&policy, - THREAD_TIME_CONSTRAINT_POLICY_COUNT); - if (kr != KERN_SUCCESS) { - mach_error("thread_policy_set:", kr); - exit(1); - } + mach_timebase_info_data_t timebase_info; + mach_timebase_info(&timebase_info); + + const uint64_t NANOS_PER_MSEC = 1000000ULL; + double clock2abs = ((double)timebase_info.denom / (double)timebase_info.numer) * NANOS_PER_MSEC; + + thread_time_constraint_policy_data_t policy; + policy.period = 0; + policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work + policy.constraint = (uint32_t)(10 * clock2abs); + policy.preemptible = FALSE; + + int kr = thread_policy_set(pthread_mach_thread_np(pthread_self()), + THREAD_TIME_CONSTRAINT_POLICY, + (thread_policy_t)&policy, + THREAD_TIME_CONSTRAINT_POLICY_COUNT); + if (kr != KERN_SUCCESS) { + mach_error("thread_policy_set:", kr); + exit(1); + } #endif - - int err; - size_t benchmarkRuns = 1; - const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); - if (envBenchmarkRuns != NULL) { - benchmarkRuns = strTo<size_t>(envBenchmarkRuns); - } - - - size_t remainingRuns = benchmarkRuns; - - // setup info object required for datamodel - GenCInterpreterInfo interpreterInfo; - interpreterInfo.name = SCXML_MACHINE_NAME; - interpreterInfo.sessionId = "rfwef"; - interpreterInfo.delayQueue.start(); - - scxml_ctx ctx; - interpreterInfo.ctx = &ctx; - - double avg = 0; - size_t microSteps = 0; + + int err; + size_t benchmarkRuns = 1; + const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); + if (envBenchmarkRuns != NULL) { + benchmarkRuns = strTo<size_t>(envBenchmarkRuns); + } + + + size_t remainingRuns = benchmarkRuns; + + // setup info object required for datamodel + GenCInterpreterInfo interpreterInfo; + interpreterInfo.name = SCXML_MACHINE_NAME; + interpreterInfo.sessionId = "rfwef"; + interpreterInfo.delayQueue.start(); + + scxml_ctx ctx; + interpreterInfo.ctx = &ctx; + + double avg = 0; + size_t microSteps = 0; #ifdef BUILD_PROFILING - double avgDm = 0; + double avgDm = 0; #endif - while(remainingRuns-- > 0) { - memset(&ctx, 0, sizeof(scxml_ctx)); - - // fresh dm (expensive :( ) - interpreterInfo.datamodel = Factory::getInstance()->createDataModel("ecmascript", &interpreterInfo); - - // set info object as user data - ctx.user_data = (void*)&interpreterInfo; - - // register callbacks with scxml context - ctx.is_enabled = &is_enabled; - ctx.is_true = &is_true; - ctx.raise_done_event = &raise_done_event; - - ctx.exec_content_send = &exec_content_send; - ctx.exec_content_raise = &exec_content_raise; - ctx.exec_content_cancel = &exec_content_cancel; - ctx.exec_content_log = &exec_content_log; - ctx.exec_content_assign = &exec_content_assign; - ctx.exec_content_foreach_init = &exec_content_foreach_init; - ctx.exec_content_foreach_next = &exec_content_foreach_next; - ctx.exec_content_foreach_done = &exec_content_foreach_done; - ctx.dequeue_external = &dequeue_external; - ctx.dequeue_internal = &dequeue_internal; - ctx.exec_content_init = &exec_content_init; - ctx.exec_content_script = &exec_content_script; - - Timer t; - t.start(); - - microSteps = 0; - while((err = scxml_step(&ctx)) == SCXML_ERR_OK) { microSteps++; } - assert(ctx.flags & SCXML_CTX_TOP_LEVEL_FINAL); - - t.stop(); - avg += t.elapsed; + while(remainingRuns-- > 0) { + memset(&ctx, 0, sizeof(scxml_ctx)); + + // fresh dm (expensive :( ) + interpreterInfo.datamodel = Factory::getInstance()->createDataModel("ecmascript", &interpreterInfo); + + // set info object as user data + ctx.user_data = (void*)&interpreterInfo; + + // register callbacks with scxml context + ctx.is_enabled = &is_enabled; + ctx.is_true = &is_true; + ctx.raise_done_event = &raise_done_event; + + ctx.exec_content_send = &exec_content_send; + ctx.exec_content_raise = &exec_content_raise; + ctx.exec_content_cancel = &exec_content_cancel; + ctx.exec_content_log = &exec_content_log; + ctx.exec_content_assign = &exec_content_assign; + ctx.exec_content_foreach_init = &exec_content_foreach_init; + ctx.exec_content_foreach_next = &exec_content_foreach_next; + ctx.exec_content_foreach_done = &exec_content_foreach_done; + ctx.dequeue_external = &dequeue_external; + ctx.dequeue_internal = &dequeue_internal; + ctx.exec_content_init = &exec_content_init; + ctx.exec_content_script = &exec_content_script; + + Timer t; + t.start(); + + microSteps = 0; + while((err = scxml_step(&ctx)) == SCXML_ERR_OK) { + microSteps++; + } + assert(ctx.flags & SCXML_CTX_TOP_LEVEL_FINAL); + + t.stop(); + avg += t.elapsed; #ifdef BUILD_PROFILING - avgDm += interpreterInfo.datamodel.timer.elapsed; - interpreterInfo.datamodel.timer.elapsed = 0; + avgDm += interpreterInfo.datamodel.timer.elapsed; + interpreterInfo.datamodel.timer.elapsed = 0; #endif - size_t passIdx = 0; - for (int i = 0; i < SCXML_NUMBER_STATES; i++) { - if (scxml_states[i].name && strcmp(scxml_states[i].name, "pass") == 0) { - passIdx = i; - break; - } - } - - assert(IS_SET(passIdx, ctx.config)); - interpreterInfo.delayQueue.cancelAllEvents(); - interpreterInfo.eq.clear(); - interpreterInfo.iq.clear(); - } - - // 14.25311111 us per microstep - // 1.923466667 us - std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms on average" << std::endl; - std::cout << microSteps << " microsteps per iteration (" << (avg * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep)" << std::endl; + size_t passIdx = 0; + for (int i = 0; i < SCXML_NUMBER_STATES; i++) { + if (scxml_states[i].name && strcmp(scxml_states[i].name, "pass") == 0) { + passIdx = i; + break; + } + } + + assert(IS_SET(passIdx, ctx.config)); + interpreterInfo.delayQueue.cancelAllEvents(); + interpreterInfo.eq.clear(); + interpreterInfo.iq.clear(); + } + + // 14.25311111 us per microstep + // 1.923466667 us + std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms on average" << std::endl; + std::cout << microSteps << " microsteps per iteration (" << (avg * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep)" << std::endl; #ifdef BUILD_PROFILING - std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; - std::cout << ((avg - avgDm) * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep \\wo datamodel" << std::endl; + std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; + std::cout << ((avg - avgDm) * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep \\wo datamodel" << std::endl; #endif - interpreterInfo.delayQueue.stop(); - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(100)); - return EXIT_SUCCESS; + interpreterInfo.delayQueue.stop(); + tthread::this_thread::sleep_for(tthread::chrono::milliseconds(100)); + return EXIT_SUCCESS; }
\ No newline at end of file diff --git a/test/src/test-datamodel.cpp b/test/src/test-datamodel.cpp index 4b93b4d..12f74e6 100644 --- a/test/src/test-datamodel.cpp +++ b/test/src/test-datamodel.cpp @@ -16,15 +16,15 @@ using namespace boost; class TestDataModelExtension : public DataModelExtension { public: TestDataModelExtension() {} - + std::string provides() { return "_x.platform.pool"; } - + Data getValueOf(const std::string& member) { return Data(true); } - + void setValueOf(const std::string& member, const Data& data) { std::cout << "Setting " << member << " to " << std::endl << Data::toJSON(data); } @@ -497,20 +497,20 @@ int main(int argc, char** argv) { std::cout << content << std::endl; assert(boost::equals(content, "There are 12 monkeys! Really 12 monkeys!")); } - + { std::string xml = - "<scxml datamodel=\"ecmascript\">" - " <script src=\"http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js\" />" - " <state id=\"s1\">" - " <onentry>" - " <script>_x.platform.pool('memeber.second', { foo: 12, bar: 34})</script>" - " <log label=\"ext\" expr=\"dump(_x.platform.pool('member.first'))\" />" - " </onentry>" - " <transition target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; + "<scxml datamodel=\"ecmascript\">" + " <script src=\"http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js\" />" + " <state id=\"s1\">" + " <onentry>" + " <script>_x.platform.pool('memeber.second', { foo: 12, bar: 34})</script>" + " <log label=\"ext\" expr=\"dump(_x.platform.pool('member.first'))\" />" + " </onentry>" + " <transition target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; TestDataModelExtension ext; Interpreter interpreter = Interpreter::fromXML(xml, ""); @@ -522,6 +522,6 @@ int main(int argc, char** argv) { state = interpreter.step(); } while (state != USCXML_FINISHED && state!= USCXML_DESTROYED); - + } }
\ No newline at end of file diff --git a/test/src/test-doneevent.cpp b/test/src/test-doneevent.cpp index d49f8e2..0330512 100644 --- a/test/src/test-doneevent.cpp +++ b/test/src/test-doneevent.cpp @@ -4,60 +4,63 @@ using namespace uscxml; // -- Issue 56 on github int main(int argc, char** argv) { - std::deque<std::string> messageQueue; - messageQueue.push_back("a"); - messageQueue.push_back("b"); - messageQueue.push_back("c"); - messageQueue.push_back("d"); - - const char* scxmlContent = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" - "<scxml xmlns=\"http://www.w3.org/2005/07/scxml\" version=\"1.0\" initial=\"initial_state\">" - " <state id=\"initial_state\">" - " <transition event=\"a\" target=\"parallel_state\"/>" - " </state>" - " <parallel id=\"parallel_state\">" - " <transition event=\"done.state.parallel_state\" target=\"join_state\"/>" - " <state id=\"p1out\" initial=\"p1\">" - " <state id=\"p1\">" - " <transition event=\"b\" target=\"p11\"/>" - " </state>" - " <final id=\"p11\"/>" - " </state>" - " <state id=\"p2out\" initial=\"p2\">" - " <state id=\"p2\">" - " <transition event=\"c\" target=\"p21\"/>" - " </state>" - " <final id=\"p21\"/>" - " </state>" - " </parallel>" - " <state id=\"join_state\">" - " <transition event=\"d\" target=\"final_state\"/>" - " </state>" - " <final id=\"final_state\"/>" - "</scxml>"; - - std::string msg; - - uscxml::Interpreter scxml = uscxml::Interpreter::fromXML(scxmlContent, ""); - scxml.addMonitor(new StateTransitionMonitor()); - - uscxml::InterpreterState state; - // assume initial stable configuration - do { state = scxml.step(); } while(state > 0); - - while(state != uscxml::USCXML_FINISHED && !messageQueue.empty()) - { - msg = messageQueue.front(); - messageQueue.pop_front(); - - scxml.receive(uscxml::Event(msg, uscxml::Event::EXTERNAL)); - - // step to next stable configuration - do { state = scxml.step(); } while(state > 0); - - } - - return EXIT_SUCCESS; + std::deque<std::string> messageQueue; + messageQueue.push_back("a"); + messageQueue.push_back("b"); + messageQueue.push_back("c"); + messageQueue.push_back("d"); + + const char* scxmlContent = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<scxml xmlns=\"http://www.w3.org/2005/07/scxml\" version=\"1.0\" initial=\"initial_state\">" + " <state id=\"initial_state\">" + " <transition event=\"a\" target=\"parallel_state\"/>" + " </state>" + " <parallel id=\"parallel_state\">" + " <transition event=\"done.state.parallel_state\" target=\"join_state\"/>" + " <state id=\"p1out\" initial=\"p1\">" + " <state id=\"p1\">" + " <transition event=\"b\" target=\"p11\"/>" + " </state>" + " <final id=\"p11\"/>" + " </state>" + " <state id=\"p2out\" initial=\"p2\">" + " <state id=\"p2\">" + " <transition event=\"c\" target=\"p21\"/>" + " </state>" + " <final id=\"p21\"/>" + " </state>" + " </parallel>" + " <state id=\"join_state\">" + " <transition event=\"d\" target=\"final_state\"/>" + " </state>" + " <final id=\"final_state\"/>" + "</scxml>"; + + std::string msg; + + uscxml::Interpreter scxml = uscxml::Interpreter::fromXML(scxmlContent, ""); + scxml.addMonitor(new StateTransitionMonitor()); + + uscxml::InterpreterState state; + // assume initial stable configuration + do { + state = scxml.step(); + } while(state > 0); + + while(state != uscxml::USCXML_FINISHED && !messageQueue.empty()) { + msg = messageQueue.front(); + messageQueue.pop_front(); + + scxml.receive(uscxml::Event(msg, uscxml::Event::EXTERNAL)); + + // step to next stable configuration + do { + state = scxml.step(); + } while(state > 0); + + } + + return EXIT_SUCCESS; }
\ No newline at end of file diff --git a/test/src/test-flat-stateid.cpp b/test/src/test-flat-stateid.cpp index fcf50b7..10d83eb 100644 --- a/test/src/test-flat-stateid.cpp +++ b/test/src/test-flat-stateid.cpp @@ -63,11 +63,11 @@ int main(int argc, char** argv) { // these will match uscxml::HistoryTransitionClass histClass1Match1("history:{h0:{s1, s2, s3}}", "history:{h0:{s0}}"); assert(histClass1.matches(histClass1Match1)); - + histClass1.merge(histClass1Match1); assert(histClass1.toRemember.at("h0").find("s0") != histClass1.toRemember.at("h0").end()); assert(histClass1.toRemember.at("h0").size() == 1); - + assert(histClass1.toForget.at("h0").find("s1") != histClass1.toForget.at("h0").end()); assert(histClass1.toForget.at("h0").find("s2") != histClass1.toForget.at("h0").end()); assert(histClass1.toForget.at("h0").find("s3") != histClass1.toForget.at("h0").end()); diff --git a/test/src/test-issue-reporting.cpp b/test/src/test-issue-reporting.cpp index 9750c58..84cc096 100644 --- a/test/src/test-issue-reporting.cpp +++ b/test/src/test-issue-reporting.cpp @@ -7,11 +7,11 @@ using namespace uscxml; std::set<std::string> issueLocationsForXML(const std::string xml) { Interpreter interpreter = Interpreter::fromXML(xml, ""); - // common xmlns and version requirement on scxml attribute - interpreter.getDocument().getDocumentElement().setAttribute("xmlns", "http://www.w3.org/2005/07/scxml"); - interpreter.getDocument().getDocumentElement().setAttribute("version", "1.0"); + // common xmlns and version requirement on scxml attribute + interpreter.getDocument().getDocumentElement().setAttribute("xmlns", "http://www.w3.org/2005/07/scxml"); + interpreter.getDocument().getDocumentElement().setAttribute("version", "1.0"); - std::list<InterpreterIssue> issues = interpreter.validate(); + std::list<InterpreterIssue> issues = interpreter.validate(); std::set<std::string> issueLocations; @@ -101,7 +101,7 @@ int main(int argc, char** argv) { if (0) { // State has no 'id' attribute - // *** This is not actually an error! *** + // *** This is not actually an error! *** const char* xml = "<scxml datamodel=\"ecmascript\">" " <state>" @@ -142,250 +142,250 @@ int main(int argc, char** argv) { assert(issueLocations.size() == 1); } - if (1) { - // Useless history 1 - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\" />" - " <state id=\"baz\" />" - " <transition event=\"e.foo\" target=\"done\" />" - " <transition event=\"e.bar\" target=\"baz\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Useless history 2 - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" - " <transition target=\"foo\" />" - " </history>" - " <transition target=\"done\" />" - " <state id=\"foo\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // No legal completion - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"foo bar\">" - " <state id=\"foo\" />" - " <state id=\"bar\" />" - " <transition target=\"foo bar\" />" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 2); - } - - if (1) { - // attribute constraints - - { - // initial attribute and <initial> child - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"foo\">" - " <initial>" - " <transition target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // initial attribute with atomic state - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // initial child with atomic state - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition target=\"start\" />" - " </initial>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.size() == 2); // also invalid non-child target state in initial - } - - // combinations of namelist, content and param - { - // send with content and namelist, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <send target=\"#_external\" namelist=\"var1\">" - " <content>Foo!</content>" - " </send>" - " </onentry>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // send with content and params, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <send target=\"#_external\">" - " <param name=\"foo\" expr=\"3\" />" - " <content>Foo!</content>" - " </send>" - " </onentry>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // send with params and namelist, perfectly acceptable - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <send target=\"#_external\" namelist=\"foo\">" - " <param name=\"foo\" expr=\"3\" />" - " </send>" - " </onentry>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.size() == 0); - } - - { - // invoke with content and src, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <invoke type=\"scxml\" src=\"var1\">" - " <content>Foo!</content>" - " </invoke>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // invoke with namelist and param, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <invoke type=\"scxml\" namelist=\"var1\">" - " <param name=\"foo\" expr=\"3\" />" - " </invoke>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // invoke with param and content, perfectly acceptable - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <invoke type=\"scxml\">" - " <param name=\"foo\" expr=\"3\" />" - " <content>Foo!</content>" - " </invoke>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.size() == 0); - } - - { - // invoke with namelist and content, perfectly acceptable - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <invoke type=\"scxml\" namelist=\"var1\">" - " <content>Foo!</content>" - " </invoke>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.size() == 0); - } - - { - // donedata with content and param, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <donedata>" - " <param name=\"foo\" expr=\"3\" />" - " <content>Foo!</content>" - " </donedata>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/donedata[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - - } - - + if (1) { + // Useless history 1 + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\" />" + " <state id=\"baz\" />" + " <transition event=\"e.foo\" target=\"done\" />" + " <transition event=\"e.bar\" target=\"baz\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Useless history 2 + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\">" + " <transition target=\"foo\" />" + " </history>" + " <transition target=\"done\" />" + " <state id=\"foo\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // No legal completion + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"foo bar\">" + " <state id=\"foo\" />" + " <state id=\"bar\" />" + " <transition target=\"foo bar\" />" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 2); + } + + if (1) { + // attribute constraints + + { + // initial attribute and <initial> child + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"foo\">" + " <initial>" + " <transition target=\"foo\" />" + " </initial>" + " <state id=\"foo\" />" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // initial attribute with atomic state + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // initial child with atomic state + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition target=\"start\" />" + " </initial>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.size() == 2); // also invalid non-child target state in initial + } + + // combinations of namelist, content and param + { + // send with content and namelist, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <onentry>" + " <send target=\"#_external\" namelist=\"var1\">" + " <content>Foo!</content>" + " </send>" + " </onentry>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // send with content and params, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <onentry>" + " <send target=\"#_external\">" + " <param name=\"foo\" expr=\"3\" />" + " <content>Foo!</content>" + " </send>" + " </onentry>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // send with params and namelist, perfectly acceptable + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <onentry>" + " <send target=\"#_external\" namelist=\"foo\">" + " <param name=\"foo\" expr=\"3\" />" + " </send>" + " </onentry>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.size() == 0); + } + + { + // invoke with content and src, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <invoke type=\"scxml\" src=\"var1\">" + " <content>Foo!</content>" + " </invoke>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // invoke with namelist and param, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <invoke type=\"scxml\" namelist=\"var1\">" + " <param name=\"foo\" expr=\"3\" />" + " </invoke>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // invoke with param and content, perfectly acceptable + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <invoke type=\"scxml\">" + " <param name=\"foo\" expr=\"3\" />" + " <content>Foo!</content>" + " </invoke>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.size() == 0); + } + + { + // invoke with namelist and content, perfectly acceptable + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <invoke type=\"scxml\" namelist=\"var1\">" + " <content>Foo!</content>" + " </invoke>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.size() == 0); + } + + { + // donedata with content and param, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <donedata>" + " <param name=\"foo\" expr=\"3\" />" + " <content>Foo!</content>" + " </donedata>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/donedata[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + + } + + if (1) { // Transition can never be optimally enabled (conditionless, eventless) @@ -433,204 +433,204 @@ int main(int argc, char** argv) { assert(issueLocations.size() == 1); } - if (1) { - // Initial attribute with target outside of children - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"foo done\">" - " <state id=\"foo\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial transition with target outside of children - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition target=\"foo done\" />" - " </initial>" - " <state id=\"foo\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial history transition with target outside of children - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" - " <transition target=\"foo done\" />" - " </history>" - " <state id=\"foo\">" - " <transition target=\"baz\" />" - " </state>" - " <state id=\"baz\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial transition with target outside of children - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition target=\"foo done\" />" - " </initial>" - " <state id=\"foo\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + if (1) { + // Initial attribute with target outside of children + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"foo done\">" + " <state id=\"foo\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial transition with target outside of children + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition target=\"foo done\" />" + " </initial>" + " <state id=\"foo\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial history transition with target outside of children + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\">" + " <transition target=\"foo done\" />" + " </history>" + " <state id=\"foo\">" + " <transition target=\"baz\" />" + " </state>" + " <state id=\"baz\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial transition with target outside of children + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition target=\"foo done\" />" + " </initial>" + " <state id=\"foo\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } if (1) { // Initial transition with event - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition event=\"e.foo\" target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition event=\"e.foo\" target=\"foo\" />" + " </initial>" + " <state id=\"foo\" />" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } - if (1) { - // Initial transition with condition - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition cond=\"true\" target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial with multiple transitions - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition target=\"foo\" />" - " <transition target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial with no transitions - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial />" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // History transition with event - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" - " <transition event=\"e.foo\" target=\"foo\" />" - " </history>" - " <state id=\"foo\">" - " <state id=\"foo.s1\">" - " <transition target=\"foo.s2\" />" - " </state>" - " <state id=\"foo.s2\" />" - " </state>" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // History transition with condition - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" - " <transition cond=\"false\" target=\"foo\" />" - " </history>" - " <state id=\"foo\">" - " <state id=\"foo.s1\">" - " <transition target=\"foo.s2\" />" - " </state>" - " <state id=\"foo.s2\" />" - " </state>" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + if (1) { + // Initial transition with condition + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition cond=\"true\" target=\"foo\" />" + " </initial>" + " <state id=\"foo\" />" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial with multiple transitions + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition target=\"foo\" />" + " <transition target=\"foo\" />" + " </initial>" + " <state id=\"foo\" />" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial with no transitions + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial />" + " <state id=\"foo\" />" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // History transition with event + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\">" + " <transition event=\"e.foo\" target=\"foo\" />" + " </history>" + " <state id=\"foo\">" + " <state id=\"foo.s1\">" + " <transition target=\"foo.s2\" />" + " </state>" + " <state id=\"foo.s2\" />" + " </state>" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // History transition with condition + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\">" + " <transition cond=\"false\" target=\"foo\" />" + " </history>" + " <state id=\"foo\">" + " <state id=\"foo.s1\">" + " <transition target=\"foo.s2\" />" + " </state>" + " <state id=\"foo.s2\" />" + " </state>" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } if (1) { // Send to unknown IO Processor @@ -730,9 +730,9 @@ int main(int argc, char** argv) { " <send>" " <param expr=\"%2345\" />" " </send>" - " <send>" - " <content expr=\"%2345\" />" - " </send>" + " <send>" + " <content expr=\"%2345\" />" + " </send>" " </onentry>" " </state>" "</scxml>"; @@ -742,7 +742,7 @@ int main(int argc, char** argv) { assert(issueLocations.find("//data[@id=\"foo\"]") != issueLocations.end()); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/assign[1]") != issueLocations.end()); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]/param[1]") != issueLocations.end()); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[2]/content[1]") != issueLocations.end()); + assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[2]/content[1]") != issueLocations.end()); assert(issueLocations.size() == 5); } diff --git a/test/src/test-misc.cpp b/test/src/test-misc.cpp index 6259d57..504b6a6 100644 --- a/test/src/test-misc.cpp +++ b/test/src/test-misc.cpp @@ -10,15 +10,15 @@ using namespace uscxml; Timer t1; bool testTimers() { - { - Measurement m(&t1); - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(1000)); - } - std::cout << t1.elapsed << std::endl; - return true; + { + Measurement m(&t1); + tthread::this_thread::sleep_for(tthread::chrono::milliseconds(1000)); + } + std::cout << t1.elapsed << std::endl; + return true; } int main(int argc, char** argv) { - testTimers(); - return 0; + testTimers(); + return 0; }
\ No newline at end of file diff --git a/test/src/test-promela-parser.cpp b/test/src/test-promela-parser.cpp index 8c8f2b4..cab19ab 100644 --- a/test/src/test-promela-parser.cpp +++ b/test/src/test-promela-parser.cpp @@ -18,7 +18,7 @@ using namespace Arabica::DOM; extern int promela_debug; void testInlinePromela() { - + DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); Document<std::string> document = domFactory.createDocument("", "", 0); @@ -38,7 +38,7 @@ void testInlinePromela() { promela-code\n \ This is foo!\ "; - + Comment<std::string> comment = document.createComment(test); PromelaInline inl(comment); assert(inl.type == PromelaInline::PROMELA_CODE); @@ -50,26 +50,26 @@ void testInlinePromela() { promela-event\n \ [{\"name\": \"e1\", \"data\": { \"foo\": \"some string\" }}, \ {\"name\": \"e1\", \"data\": { \"bar\": 12 }}]"; - + Comment<std::string> comment = document.createComment(test); PromelaInline inl(comment); assert(inl.type == PromelaInline::PROMELA_EVENT_ONLY); - + PromelaEventSource es(inl); assert(es.events.array.size() == 2); - + } { Interpreter interpreter = Interpreter::fromURL("/Users/sradomski/Documents/TK/Code/uscxml/test/uscxml/promela/test-event-source-auto.scxml"); assert(interpreter); PromelaInlines inls(interpreter.getDocument().getDocumentElement()); - + assert(inls.getAllOfType(PromelaInline::PROMELA_EVENT_ONLY).size() == 1); assert(inls.getAllOfType(PromelaInline::PROMELA_EVENT_ALL_BUT).size() == 1); interpreter.getImpl()->getState("s0"); } - + #if 0 { std::string test = "\ @@ -80,8 +80,8 @@ void testInlinePromela() { assert(prmInls.nrAcceptLabels == 0 && prmInls.nrCodes == 1 && prmInls.nrEventSources == 0 && - prmInls.nrEndLabels == 0 && - prmInls.nrAcceptLabels == 0 && + prmInls.nrEndLabels == 0 && + prmInls.nrAcceptLabels == 0 && prmInls.nrProgressLabels == 0); assert(prmInls.code.size() == 1); assert(prmInls.code.front().type == PromelaInline::PROMELA_CODE); @@ -191,13 +191,13 @@ void testInlinePromela() { "; PromelaInlines prmInls = PromelaInlines::fromString(test); assert(prmInls.nrAcceptLabels == 0 && - prmInls.nrCodes == 0 && - prmInls.nrEventSources == 1 && - prmInls.nrEndLabels == 0 && - prmInls.nrProgressLabels == 0); + prmInls.nrCodes == 0 && + prmInls.nrEventSources == 1 && + prmInls.nrEndLabels == 0 && + prmInls.nrProgressLabels == 0); assert(prmInls.code.size() == 1); assert(prmInls.code.front().type == PromelaInline::PROMELA_EVENT_SOURCE_CUSTOM); - + PromelaEventSource pmlES(prmInls.code.front()); assert(pmlES.sequences.size() == 0); @@ -212,10 +212,10 @@ void testInlinePromela() { "; PromelaInlines prmInls = PromelaInlines::fromString(test); assert(prmInls.nrAcceptLabels == 0 && - prmInls.nrCodes == 0 && - prmInls.nrEventSources == 1 && - prmInls.nrEndLabels == 0 && - prmInls.nrProgressLabels == 1); + prmInls.nrCodes == 0 && + prmInls.nrEventSources == 1 && + prmInls.nrEndLabels == 0 && + prmInls.nrProgressLabels == 1); assert(prmInls.code.size() == 2); assert(prmInls.code.front().type == PromelaInline::PROMELA_EVENT_SOURCE_CUSTOM); @@ -269,7 +269,7 @@ void testPromelaParser() { expressions.push_back("_event.data[1].aParam.key1.key2[1].key3.key4"); expressions.push_back("\n\n\n\n int foo = 3;\n\nint bar = 5;"); - + /* expressions */ expressions.push_back("i+1"); expressions.push_back("(x == false || t == Bturn);"); diff --git a/test/src/test-url.cpp b/test/src/test-url.cpp index 1ebcac3..d4aa0c0 100644 --- a/test/src/test-url.cpp +++ b/test/src/test-url.cpp @@ -66,7 +66,7 @@ void testFileURLs() { // absURLs.push_back(URL("/Users/sradomski/Desktop/"));
// absURLs.push_back(URL("/Users/sradomski/Desktop/foo.txt"));
}
-
+
std::list<URL> absWithHostURLs;
{
absWithHostURLs.push_back(URL("file://hostname/"));
@@ -82,17 +82,17 @@ void testFileURLs() { }
// relative URLs
std::list<URL> relURLs;
-
+
{
relURLs.push_back(URL("file"));
relURLs.push_back(URL("file:"));
relURLs.push_back(URL("file://"));
-
+
// platform specific
relURLs.push_back(URL("file:Macintosh%20HD/fileURLs/text.txt"));
relURLs.push_back(URL("file:fileURLs/text.txt"));
relURLs.push_back(URL("file:Document/Text.foo"));
-
+
// usual filesystem paths
relURLs.push_back(URL("Users\\sradomski\\Desktop\\foo.txt"));
relURLs.push_back(URL("Document\\Some Spaces\\index.txt"));
@@ -111,7 +111,7 @@ void testFileURLs() { for (std::list<URL>::iterator relIter = relURLs.begin(); relIter != relURLs.end(); relIter++) {
assert(!relIter->isAbsolute());
}
-
+
for (std::list<URL>::iterator absIter = absURLs.begin(); absIter != absURLs.end(); absIter++) {
for (std::list<URL>::iterator relIter = relURLs.begin(); relIter != relURLs.end(); relIter++) {
URL relURL(*relIter);
@@ -265,7 +265,7 @@ int main(int argc, char** argv) { content << url;
}
#endif
-
+
{
URL url("test/index.html");
assert(iequals(url.scheme(), ""));
diff --git a/test/src/test-w3c.cpp b/test/src/test-w3c.cpp index 2c2f4da..3de8e4d 100644 --- a/test/src/test-w3c.cpp +++ b/test/src/test-w3c.cpp @@ -36,39 +36,39 @@ int retCode = EXIT_FAILURE; uscxml::Interpreter interpreter; void printUsageAndExit(const char* progName) { - // remove path from program name - std::string progStr(progName); - if (progStr.find_last_of(PATH_SEPERATOR) != std::string::npos) { - progStr = progStr.substr(progStr.find_last_of(PATH_SEPERATOR) + 1, progStr.length() - (progStr.find_last_of(PATH_SEPERATOR) + 1)); - } - - printf("%s version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n", progStr.c_str()); - printf("Usage\n"); - printf("\t%s", progStr.c_str()); - printf(" [-f] [-dN] [-bN]"); + // remove path from program name + std::string progStr(progName); + if (progStr.find_last_of(PATH_SEPERATOR) != std::string::npos) { + progStr = progStr.substr(progStr.find_last_of(PATH_SEPERATOR) + 1, progStr.length() - (progStr.find_last_of(PATH_SEPERATOR) + 1)); + } + + printf("%s version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n", progStr.c_str()); + printf("Usage\n"); + printf("\t%s", progStr.c_str()); + printf(" [-f] [-dN] [-bN]"); #ifdef BUILD_AS_PLUGINS - printf(" [-p pluginPath]"); + printf(" [-p pluginPath]"); #endif - printf(" URL"); - printf("\n"); - printf("Options\n"); - printf("\t-f : flatten to SCXML state-machine\n"); - printf("\t-d FACTOR : delay factor\n"); - printf("\t-b ITERATIONS : benchmark with number of runs\n"); - printf("\n"); - exit(1); + printf(" URL"); + printf("\n"); + printf("Options\n"); + printf("\t-f : flatten to SCXML state-machine\n"); + printf("\t-d FACTOR : delay factor\n"); + printf("\t-b ITERATIONS : benchmark with number of runs\n"); + printf("\n"); + exit(1); } class W3CStatusMonitor : public uscxml::InterpreterMonitor { -void beforeCompletion(uscxml::Interpreter tmp) { - if (interpreter.getConfiguration().size() == 1 && interpreter.isInState("pass")) { - std::cout << "TEST SUCCEEDED" << std::endl; - retCode = EXIT_SUCCESS; - return; + void beforeCompletion(uscxml::Interpreter tmp) { + if (interpreter.getConfiguration().size() == 1 && interpreter.isInState("pass")) { + std::cout << "TEST SUCCEEDED" << std::endl; + retCode = EXIT_SUCCESS; + return; + } + std::cout << "TEST FAILED" << std::endl; } - std::cout << "TEST FAILED" << std::endl; -} }; int main(int argc, char** argv) { @@ -103,22 +103,22 @@ int main(int argc, char** argv) { case 'd': delayFactor = strTo<double>(optarg); break; - case 'b': - benchmarkRuns = strTo<size_t>(optarg); - break; + case 'b': + benchmarkRuns = strTo<size_t>(optarg); + break; default: break; } } - - const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); - if (envBenchmarkRuns != NULL) { - benchmarkRuns = strTo<size_t>(envBenchmarkRuns); - } - + + const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); + if (envBenchmarkRuns != NULL) { + benchmarkRuns = strTo<size_t>(envBenchmarkRuns); + } + documentURI = argv[optind]; - LOG(INFO) << "Processing " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)) << (benchmarkRuns > 0 ? " for " + toStr(benchmarkRuns) + " benchmarks" : ""); + LOG(INFO) << "Processing " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)) << (benchmarkRuns > 0 ? " for " + toStr(benchmarkRuns) + " benchmarks" : ""); if (withFlattening) { interpreter = Interpreter::fromURL(documentURI); Transformer flattener = ChartToFlatSCXML::transform(interpreter); @@ -127,7 +127,7 @@ int main(int argc, char** argv) { } else { interpreter = Interpreter::fromURL(documentURI); } - + if (delayFactor != 1) { Arabica::DOM::Document<std::string> document = interpreter.getDocument(); Arabica::DOM::Element<std::string> root = document.getDocumentElement(); @@ -159,53 +159,53 @@ int main(int argc, char** argv) { } if (interpreter) { - W3CStatusMonitor* vm = new W3CStatusMonitor(); - interpreter.addMonitor(vm); + W3CStatusMonitor* vm = new W3CStatusMonitor(); + interpreter.addMonitor(vm); - if (benchmarkRuns > 0) { - LOG(INFO) << "Benchmarking " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)); + if (benchmarkRuns > 0) { + LOG(INFO) << "Benchmarking " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)); - InterpreterState state = interpreter.getState(); + InterpreterState state = interpreter.getState(); - double avg = 0; + double avg = 0; #ifdef BUILD_PROFILING - double avgDm = 0; - double avgStep = 0; + double avgDm = 0; + double avgStep = 0; #endif - size_t remainingRuns = benchmarkRuns; - uint64_t start = tthread::chrono::system_clock::now(); - - while(remainingRuns-- > 0) { - Timer t; - t.start(); - for(;;) { - state = interpreter.step(true); - if (state == USCXML_FINISHED) { + size_t remainingRuns = benchmarkRuns; + uint64_t start = tthread::chrono::system_clock::now(); + + while(remainingRuns-- > 0) { + Timer t; + t.start(); + for(;;) { + state = interpreter.step(true); + if (state == USCXML_FINISHED) { #ifdef BUILD_PROFILING - avgDm += interpreter.getDataModel().timer.elapsed; - interpreter.getDataModel().timer.reset(); - avgStep += interpreter.timer.elapsed; + avgDm += interpreter.getDataModel().timer.elapsed; + interpreter.getDataModel().timer.reset(); + avgStep += interpreter.timer.elapsed; #endif - } - if (state < 0) - break; - } - t.stop(); - avg += t.elapsed; - interpreter.reset(); - } - uint64_t totalDuration = tthread::chrono::system_clock::now() - start; - std::cout << benchmarkRuns << " iterations in " << totalDuration << " ms" << std::endl; - std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms on average" << std::endl; + } + if (state < 0) + break; + } + t.stop(); + avg += t.elapsed; + interpreter.reset(); + } + uint64_t totalDuration = tthread::chrono::system_clock::now() - start; + std::cout << benchmarkRuns << " iterations in " << totalDuration << " ms" << std::endl; + std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms on average" << std::endl; #ifdef BUILD_PROFILING - std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; - std::cout << (avgStep * 1000.0) / (double)benchmarkRuns << " ms in microsteps" << std::endl; + std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; + std::cout << (avgStep * 1000.0) / (double)benchmarkRuns << " ms in microsteps" << std::endl; #endif - } else { - interpreter.start(); - while(interpreter.runOnMainThread(25)); - } + } else { + interpreter.start(); + while(interpreter.runOnMainThread(25)); + } } } catch(Event e) { std::cout << e << std::endl; |