Browse Source

A <slot> element in a test contains set of output events of a nonempty big step.

Joeri Exelmans 5 years ago
parent
commit
3b1dc3aea2
27 changed files with 262234 additions and 384 deletions
  1. 1 1
      src/sccd/compiler/sccdc.py
  2. 23 0
      src/sccd/compiler/schema/sccd-core.xsd
  3. 79 90
      src/sccd/compiler/sccd.xsd
  4. 52 23
      src/sccd/runtime/statecharts_core.py
  5. 261359 0
      test/pssm/PSSM_TestSuite.xmi
  6. 57 0
      test/scxml/schemas/scxml-attribs.xsd
  7. 35 0
      test/scxml/schemas/scxml-contentmodels.xsd
  8. 26 0
      test/scxml/schemas/scxml-copyright.xsd
  9. 203 0
      test/scxml/schemas/scxml-datatypes.xsd
  10. 16 16
      test/scxml/tests/test144.txml
  11. 10 0
      test/scxml/transform.sh
  12. 40 0
      test/scxml/txml_to_sccd.xsl
  13. 3 2
      test/semantics/big_step_maximality/00_take_one.xml
  14. 3 2
      test/semantics/big_step_maximality/01_take_many.xml
  15. 3 2
      test/semantics/big_step_maximality/10_orthogonal_take_one.xml
  16. 6 4
      test/semantics/big_step_maximality/11_orthogonal_take_many.xml
  17. 13 18
      test/semantics/event_lifeline/event_consuming_whole.xml
  18. 88 0
      test/semantics/event_lifeline/41_event_consuming_whole_take_many.xml
  19. 8 8
      test/semantics/original_semantics/after.xml
  20. 0 3
      test/semantics/original_semantics/associate_event.xml
  21. 4 1
      test/semantics/original_semantics/correct_duplicate_state_id.xml
  22. 114 117
      test/semantics/original_semantics/enter_exit_hierarchy.xml
  23. 31 35
      test/semantics/original_semantics/event_consuming.xml
  24. 0 2
      test/semantics/original_semantics/event_consuming_2.xml
  25. 32 30
      test/semantics/original_semantics/history.xml
  26. 0 3
      test/semantics/original_semantics/object_manager.xml
  27. 28 27
      test/test.py

+ 1 - 1
src/sccd/compiler/sccdc.py

@@ -19,7 +19,7 @@ COMPILER_SRC_DIR = os.path.dirname(os.path.abspath(__file__))
 
 def generate(input_file, output_file, target_language, platform):
 
-	schema = ET.XMLSchema(ET.parse(os.path.join(COMPILER_SRC_DIR, "sccd.xsd")))
+	schema = ET.XMLSchema(ET.parse(os.path.join(COMPILER_SRC_DIR, "schema", "sccd.xsd")))
 	tree = ET.parse(input_file)
 	schema.assertValid(tree)
 	

+ 23 - 0
src/sccd/compiler/schema/sccd-core.xsd

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+  xmlns:sccd="msdl.uantwerpen.be/sccd"
+  targetNamespace="msdl.uantwerpen.be/sccd"
+  elementFormDefault="qualified"
+  attributeFormDefault="unqualified">
+
+  <xsd:element name="scxml">
+    <xsd:complexType>
+      <xsd:complexContent>
+        <xsd:extension base="sccd:orState">
+          <xsd:attributeGroup ref="sccd:semanticOptions"/>
+        </xsd:extension>
+      </xsd:complexContent>
+    </xsd:complexType>
+    <xsd:unique name="uniqueScxmlChildren">
+      <xsd:selector xpath="state|parallel|history"/>
+      <xsd:field xpath="@id"/>
+    </xsd:unique>
+  </xsd:element>
+  
+</xsd:schema>

+ 79 - 90
src/sccd/compiler/sccd.xsd

@@ -6,6 +6,8 @@
   elementFormDefault="qualified"
   attributeFormDefault="unqualified">
 
+  <xsd:include schemaLocation="sccd-core.xsd"/>
+
   <!-- First, some type declarations... -->
 
   <xsd:simpleType name="identifier">
@@ -16,6 +18,7 @@
 
   <xsd:simpleType name="stateId">
     <xsd:restriction base="sccd:identifier"/>
+    <!-- <xsd:restriction base="xsd:ID"/> -->
   </xsd:simpleType>
 
   <xsd:simpleType name="portName">
@@ -96,93 +99,87 @@
     </xsd:choice>
   </xsd:group>
 
-  <!--
-       Recursive type.
+  <xsd:complexType name="actionSequence">
+    <xsd:group ref="sccd:action" maxOccurs="unbounded"/>
+  </xsd:complexType>
 
-       Basically all the common stuff of basic/or/and states.
-       An element of this type does not have an 'id' attribute, but all its children
-       states do.
-       The reason we don't include state id's at the highest level is because
-       the root element <scxml> is also a state (an or-state, to be specific),
-       but it has no id.
-  -->
-  <xsd:complexType name="commonState" abstract="true">
-    <xsd:sequence>
-      <xsd:element name="onentry" minOccurs="0">
-        <xsd:complexType>
-          <xsd:group ref="sccd:action" maxOccurs="unbounded"/>
-        </xsd:complexType>
-      </xsd:element>
-      <xsd:element name="onexit" minOccurs="0">
-        <xsd:complexType>
-          <xsd:group ref="sccd:action" maxOccurs="unbounded"/>
-        </xsd:complexType>
-      </xsd:element>
-      <xsd:choice minOccurs="0" maxOccurs="unbounded">
-        <!-- Every state can have any number of <state> and <parallel> elements in it.
-             These elements always have an 'id' attribute. -->
-        <xsd:element name="state">
-          <xsd:complexType>
-            <xsd:complexContent>
-              <xsd:extension base="sccd:orState">
-                <xsd:attribute name="id" type="sccd:stateId" use="required"/>
-              </xsd:extension>
-            </xsd:complexContent>
-          </xsd:complexType>
-        </xsd:element>
-        <xsd:element name="parallel">
-          <xsd:complexType>
-            <xsd:complexContent>
-              <xsd:extension base="sccd:commonState">
-                <xsd:attribute name="id" type="sccd:stateId" use="required"/>
-              </xsd:extension>
-            </xsd:complexContent>
-          </xsd:complexType>
-        </xsd:element>
-        <xsd:element name="history">
-          <xsd:complexType>
-            <xsd:complexContent>
-              <xsd:extension base="sccd:commonState">
-                <xsd:attribute name="id" type="sccd:stateId" use="required"/>
-                <xsd:attribute name="type">
-                  <xsd:simpleType>
-                    <xsd:restriction base="xsd:string">
-                      <xsd:enumeration value="shallow"/>
-                      <xsd:enumeration value="deep"/>
-                    </xsd:restriction>
-                  </xsd:simpleType>
-                </xsd:attribute>
-              </xsd:extension>
-            </xsd:complexContent>
-          </xsd:complexType>
-        </xsd:element>
-        <xsd:element name="transition">
-          <xsd:complexType>
-            <xsd:sequence>
-              <xsd:element name="parameter" minOccurs="0" maxOccurs="unbounded">
-                <xsd:complexType>
-                  <xsd:attribute name="name" type="sccd:identifier"/>
-                  <xsd:attribute name="type" type="sccd:type"/>
-                </xsd:complexType>
-              </xsd:element>
-              <xsd:group ref="sccd:action" minOccurs="0" maxOccurs="unbounded"/>
-            </xsd:sequence>
-            <xsd:attribute name="target" type="xsd:string" use="required"/>
-            <xsd:attribute name="event" type="sccd:eventName"/>
-            <xsd:attribute name="after" type="sccd:duration"/>
-            <xsd:attribute name="cond" type="sccd:expression"/>
-            <xsd:attribute name="port" type="sccd:portName"/>
-          </xsd:complexType>
-        </xsd:element>
-      </xsd:choice>
-    </xsd:sequence>
+  <xsd:complexType name="pseudoState" abstract="true">
+    <xsd:attribute name="id" type="sccd:stateId"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="commonState">
+    <xsd:complexContent>
+      <xsd:extension base="sccd:pseudoState">
+        <xsd:sequence>
+          <xsd:element name="onentry" minOccurs="0" type="sccd:actionSequence"/>
+          <xsd:element name="onexit" minOccurs="0" type="sccd:actionSequence"/>
+          <xsd:choice minOccurs="0" maxOccurs="unbounded">
+            <xsd:element name="state" type="sccd:orState">
+              <xsd:unique name="uniqueOrStateChildren">
+                <xsd:selector xpath="state|parallel|history"/>
+                <xsd:field xpath="@id"/>
+              </xsd:unique>
+            </xsd:element>
+            <xsd:element name="parallel" type="sccd:commonState">
+              <xsd:unique name="uniqueAndStateChildren">
+                <xsd:selector xpath="state|parallel|history"/>
+                <xsd:field xpath="@id"/>
+              </xsd:unique>
+            </xsd:element>
+            <xsd:element name="history">
+              <xsd:complexType>
+                <xsd:complexContent>
+                  <xsd:extension base="sccd:pseudoState">
+                    <xsd:sequence>
+                      <!-- history pseudostate can have 1 <transition> element to indicate default history state -->
+                      <!-- this is not an actual transition -->
+                      <xsd:element name="transition" minOccurs="0">
+                        <xsd:complexType>
+                          <xsd:attribute name="target" type="xsd:string"/>
+                        </xsd:complexType>
+                      </xsd:element>
+                    </xsd:sequence>
+                    <!-- <xsd:attribute name="id" type="sccd:stateId" use="required"/> -->
+                    <xsd:attribute name="type">
+                      <xsd:simpleType>
+                        <xsd:restriction base="xsd:string">
+                          <xsd:enumeration value="shallow"/>
+                          <xsd:enumeration value="deep"/>
+                        </xsd:restriction>
+                      </xsd:simpleType>
+                    </xsd:attribute>
+                  </xsd:extension>
+                </xsd:complexContent>
+              </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="transition">
+              <xsd:complexType>
+                <xsd:sequence>
+                  <xsd:element name="parameter" minOccurs="0" maxOccurs="unbounded">
+                    <xsd:complexType>
+                      <xsd:attribute name="name" type="sccd:identifier"/>
+                      <xsd:attribute name="type" type="sccd:type"/>
+                    </xsd:complexType>
+                  </xsd:element>
+                  <xsd:group ref="sccd:action" minOccurs="0" maxOccurs="unbounded"/>
+                </xsd:sequence>
+                <xsd:attribute name="target" type="xsd:string" use="required"/>
+                <xsd:attribute name="event" type="sccd:eventName"/>
+                <xsd:attribute name="after" type="sccd:duration"/>
+                <xsd:attribute name="cond" type="sccd:expression"/>
+                <xsd:attribute name="port" type="sccd:portName"/>
+              </xsd:complexType>
+            </xsd:element>
+          </xsd:choice>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
   </xsd:complexType>
 
-  <!-- Just like commonState, also without 'id' attribute -->
   <xsd:complexType name="orState">
     <xsd:complexContent>
       <xsd:extension base="sccd:commonState">
-        <xsd:attribute name="initial" type="xsd:string"/>
+        <xsd:attribute name="initial" type="sccd:stateId"/>
       </xsd:extension>
     </xsd:complexContent>
   </xsd:complexType>
@@ -274,14 +271,7 @@
                 </xsd:complexType>
               </xsd:element>
               <xsd:element name="constructor" minOccurs="0" type="sccd:method"/>
-              <xsd:element name="scxml" minOccurs="0">
-                <xsd:complexType>
-                  <xsd:complexContent>
-                    <xsd:extension base="sccd:orState">
-                      <xsd:attributeGroup ref="sccd:semanticOptions"/>
-                    </xsd:extension>
-                  </xsd:complexContent>
-                </xsd:complexType>
+              <xsd:element ref="sccd:scxml" minOccurs="0">
               </xsd:element>
             </xsd:sequence>
             <xsd:attribute name="name" type="sccd:className" use="required"/>
@@ -330,7 +320,6 @@
                   </xsd:sequence>
                 </xsd:complexType>
               </xsd:element>
-              <!-- <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> -->
             </xsd:sequence>
           </xsd:complexType>
         </xsd:element>

+ 52 - 23
src/sccd/runtime/statecharts_core.py

@@ -430,15 +430,24 @@ class Event(object):
         return representation
     
 class OutputListener(object):
-    def __init__(self, port_names):
-        if not isinstance(port_names, list):
-            port_names = [port_names]
-        self.port_names = [port_name.port_name if isinstance(port_name, OutputPortEntry) else port_name for port_name in port_names]
-        self.queue = Queue()
-
-    def add(self, event):
-        if len(self.port_names) == 0 or event.getPort() in self.port_names:
-            self.queue.put_nowait(event)
+    def __init__(self):
+        # if not isinstance(port_names, list):
+            # port_names = [port_names]
+        # self.port_names = [port_name.port_name if isinstance(port_name, OutputPortEntry) else port_name for port_name in port_names]
+        self.queue = Queue() # queue of lists of event objects
+
+    # replaced by addBigStepOutput
+    # def add(self, event):
+    #     if len(self.port_names) == 0 or event.getPort() in self.port_names:
+    #         self.queue.put_nowait(event)
+
+    """
+    Parameters
+    ----------
+    events: list of Event objects
+    """
+    def addBigStepOutput(self, events):
+        self.queue.put_nowait(events)
             
     """ Tries for timeout seconds to fetch an event, returns None if failed.
         0 as timeout means no waiting (blocking), returns None if queue is empty.
@@ -479,7 +488,7 @@ class ControllerBase(object):
 
         # keep track of output ports
         self.output_ports = {}
-        self.output_listeners = []
+        self.output_listeners = {} # dictionary from port name to list of OutputListener objects
         
         self.simulated_time = None
         self.behind = False
@@ -509,6 +518,7 @@ class ControllerBase(object):
             port_name = "private_" + str(self.private_port_counter) + "_" + virtual_name
             self.private_port_counter += 1
         self.output_ports[port_name] = OutputPortEntry(port_name, virtual_name, instance)
+        self.output_listeners[port_name] = []
         return port_name
 
     def broadcast(self, new_event, time_offset = 0):
@@ -554,17 +564,31 @@ class ControllerBase(object):
             else:
                 target_instance.addEvent(e, event_time - self.simulated_time)
 
-    def outputEvent(self, event):
-        for listener in self.output_listeners:
-            listener.add(event)
+    """
+    Called at the end of every big step.
 
-    def addOutputListener(self, ports):
-        listener = OutputListener(ports)
-        self.output_listeners.append(listener)
+    Parameters
+    ----------
+    events: dictionary from port name to list of event objects
+    """
+    def outputBigStep(self, events):
+        for port, event_list in events.items():
+            for listener in self.output_listeners[port]:
+                listener.addBigStepOutput(event_list)
+
+    def createOutputListener(self, ports):
+        listener = OutputListener()
+        self.addOutputListener(ports, listener)
         return listener
 
-    def addMyOwnOutputListener(self, listener):
-        self.output_listeners.append(listener)
+    def addOutputListener(self, ports, listener):
+        if len(ports) == 0:
+            # add to all the ports
+            for ls in self.output_listeners.values():
+                ls.append(listener)
+        else:
+            for port in ports:
+                self.output_listeners[port].append(listener)
             
     def getObjectManager(self):
         return self.object_manager
@@ -1102,8 +1126,10 @@ class RuntimeClassBase(object):
             self.events.add(event_time, e)
 
     def processBigStepOutput(self):
-        for e in self.big_step.output_events_port:
-            self.controller.outputEvent(e)
+        # print("processBigStepOutput:", self.big_step.output_events_port)
+        self.controller.outputBigStep(self.big_step.output_events_port)
+        # for e in self.big_step.output_events_port:
+            # self.controller.outputEvent(e)
         for e in self.big_step.output_events_om:
             self.controller.object_manager.addEvent(e)
             
@@ -1249,18 +1275,21 @@ class RuntimeClassBase(object):
 class BigStepState(object):
     def __init__(self):
         self.input_events = [] # input events received from environment before beginning of big step (e.g. from object manager, from input port)
-        self.output_events_port = [] # output events to be sent to output port after big step ends.
+        self.output_events_port = {} # output events to be sent to output port after big step ends. dictionary from port name to list of event objects
         self.output_events_om = [] # output events to be sent to object manager after big step ends.
         self.has_stepped = True
 
     def next(self, input_events):
         self.input_events = input_events
-        self.output_events_port = []
+        self.output_events_port = {}
         self.output_events_om = []
         self.has_stepped = False
 
     def outputEvent(self, event):
-        self.output_events_port.append(event)
+        if event.port in self.output_events_port:
+            self.output_events_port[event.port].append(event)
+        else:
+            self.output_events_port[event.port] = [event]
 
     def outputEventOM(self, event):
         self.output_events_om.append(event)

File diff suppressed because it is too large
+ 261359 - 0
test/pssm/PSSM_TestSuite.xmi


+ 57 - 0
test/scxml/schemas/scxml-attribs.xsd

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="http://www.w3.org/2005/07/scxml"
+    xmlns="http://www.w3.org/2005/07/scxml"
+    elementFormDefault="qualified">
+	<xsd:annotation>
+		<xsd:documentation>
+		This is the XML Schema common attributes for SCXML
+		</xsd:documentation>
+		<xsd:documentation source="scxml-copyright.xsd"/>
+	</xsd:annotation>
+	<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd">
+		<xsd:annotation>
+			<xsd:documentation>
+			This import brings in the XML namespace attributes
+			The module itself does not provide the schemaLocation
+			and expects the driver schema to provide the
+			actual SchemaLocation.
+		  </xsd:documentation>
+		</xsd:annotation>
+	</xsd:import>
+	<xsd:include schemaLocation="scxml-datatypes.xsd">
+		<xsd:annotation>
+			<xsd:documentation>
+			This include  brings in the SCXML datatypes.
+			</xsd:documentation>
+		</xsd:annotation>
+	</xsd:include>
+	
+	<xsd:attributeGroup name="Fetchtimeout.attrib">
+		<xsd:annotation>
+			<xsd:documentation>Used in Cache.attribs</xsd:documentation>
+		</xsd:annotation>
+		<xsd:attribute name="fetchtimeout" type="Duration.datatype"/>
+	</xsd:attributeGroup>
+	<xsd:attributeGroup name="Maxage.attrib">
+		<xsd:annotation>
+			<xsd:documentation>Used in Cache.attribs</xsd:documentation>
+		</xsd:annotation>
+		<xsd:attribute name="maxage" type="Integer.datatype"/>
+	</xsd:attributeGroup>
+	<xsd:attributeGroup name="Maxstale.attrib">
+		<xsd:annotation>
+			<xsd:documentation>Used in Cache attribs</xsd:documentation>
+		</xsd:annotation>
+		<xsd:attribute name="maxstale" type="Integer.datatype"/>
+	</xsd:attributeGroup>
+
+	<xsd:attributeGroup name="Cache.attribs">
+		<xsd:annotation>
+			<xsd:documentation>Cache attributes to control caching behavior</xsd:documentation>
+		</xsd:annotation>
+		<xsd:attributeGroup ref="Fetchtimeout.attrib"/>
+		<xsd:attributeGroup ref="Maxage.attrib"/>
+		<xsd:attributeGroup ref="Maxstale.attrib"/>
+	</xsd:attributeGroup>
+</xsd:schema>

+ 35 - 0
test/scxml/schemas/scxml-contentmodels.xsd

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="http://www.w3.org/2005/07/scxml"
+    xmlns="http://www.w3.org/2005/07/scxml"
+    elementFormDefault="qualified">
+	<xsd:annotation>
+		<xsd:documentation>
+         XML Schema content models for SCXML
+         * scxml.extra.content 
+         * content
+         * scxml.extra.attribs
+         Defines SCXML shared content models.
+        </xsd:documentation>
+		<xsd:documentation source="scxml-copyright.xsd"/>
+	</xsd:annotation>
+	
+	<xsd:attributeGroup name="scxml.extra.attribs">
+		<xsd:annotation>
+			<xsd:documentation>group allowing attributes from other namespaces</xsd:documentation>
+		</xsd:annotation>
+		<xsd:anyAttribute namespace="##other" processContents="lax"/>
+	</xsd:attributeGroup>
+	
+	<xsd:group name="scxml.extra.content">
+		<xsd:annotation>
+			<xsd:documentation>
+				group allowing elements from other namespaces
+                        </xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+		</xsd:sequence>
+	</xsd:group>
+	
+</xsd:schema>

+ 26 - 0
test/scxml/schemas/scxml-copyright.xsd

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="http://www.w3.org/2005/07/scxml"
+    xmlns="http://www.w3.org/2005/07/scxml"
+    elementFormDefault="qualified">
+
+  <xsd:annotation>
+    <xsd:documentation>
+    This is the XML Schema for SCXML 1.0, formulated as a modular XML application
+    Copyright &#169;1998-2007 World Wide Web Consortium
+    (Massachusetts Institute of Technology, European Research Consortium
+     for Informatics and Mathematics, Keio University).
+    All Rights Reserved.
+  
+    Permission to use, copy, modify and distribute the SCXML Schema
+    modules and their accompanying xs:documentation for any purpose
+    and without fee is hereby granted in perpetuity, provided that the above
+    copyright notice and this paragraph appear in all copies.  
+    The copyright holders make no representation about the suitability of
+    these XML Schema modules for any purpose.
+  
+    They are provided "as is" without expressed or implied warranty.
+    </xsd:documentation>
+  </xsd:annotation>
+
+</xsd:schema>

+ 203 - 0
test/scxml/schemas/scxml-datatypes.xsd

@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="http://www.w3.org/2005/07/scxml"
+    xmlns="http://www.w3.org/2005/07/scxml"
+    elementFormDefault="qualified">
+
+	<xsd:annotation>
+		<xsd:documentation>
+        XML Schema datatypes for SCXML
+
+        Defines containers for the SCXML datatypes, many of these
+        imported from other specifications and standards.
+
+		</xsd:documentation>
+		<xsd:documentation source="scxml-copyright.xsd"/>
+	</xsd:annotation>
+
+	<xsd:simpleType name="Exmode.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+            Describes the processor execution mode for this document, being
+            either "lax" or "strict".     
+			</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:NMTOKEN">
+			<xsd:enumeration value="lax"/>
+			<xsd:enumeration value="strict"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+
+	<xsd:simpleType name="Binding.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+            The binding type in use for the SCXML document.     
+			</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:NMTOKEN">
+			<xsd:enumeration value="early"/>
+			<xsd:enumeration value="late"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+
+
+	<xsd:simpleType name="HistoryType.datatype">
+		<xsd:restriction base="xsd:string">
+			<xsd:enumeration value="shallow"/>
+			<xsd:enumeration value="deep"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+
+	<xsd:simpleType name="TransitionType.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+            The type of the transition i.e. internal or external. 
+			</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:NMTOKEN">
+			<xsd:enumeration value="internal"/>
+			<xsd:enumeration value="external"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+
+	<xsd:simpleType name="Boolean.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+            Boolean: true or false only
+			</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:NMTOKENS">
+			<xsd:enumeration value="true"/>
+			<xsd:enumeration value="false"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+
+	<xsd:simpleType name="AssignType.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+            The assign type that allows for precise manipulation of the
+            datamodel location. Types are:
+                 replacechildren (default),
+                 firstchild, lastchild,
+                 previoussibling, nextsibling,
+                 replace, delete,
+                 addattribute
+			</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:NMTOKEN">
+			<xsd:enumeration value="replacechildren"/>
+			<xsd:enumeration value="firstchild"/>
+			<xsd:enumeration value="lastchild"/>
+			<xsd:enumeration value="previoussibling"/>
+			<xsd:enumeration value="nextsibling"/>
+			<xsd:enumeration value="replace"/>
+			<xsd:enumeration value="delete"/>
+			<xsd:enumeration value="addattribute"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+
+	<xsd:simpleType name="URI.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+            The xsd:anyURI type and thus URI references in SCXML
+            documents may contain a wide array of international
+            characters. Implementers should reference RFC 3987 and
+            the "Character Model for the World Wide Web 1.0:
+            Resource Identifiers" in order to provide appropriate
+            support for these characters in VoiceXML documents and
+            when processing values of this type or mapping them to
+            URIs.
+			</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:anyURI"/>
+	</xsd:simpleType>
+
+	<xsd:simpleType name="Integer.datatype">
+		<xsd:annotation>
+			<xsd:documentation>Non-negative integer</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:nonNegativeInteger"/>
+	</xsd:simpleType>
+
+	<xsd:simpleType name="Duration.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+            Duration allowing positive values ranging from milliseconds
+            to days. 
+			</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:string">
+			<xsd:pattern value="\d*(\.\d+)?(ms|s|m|h|d)"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+
+
+	<xsd:simpleType name="EventType.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+            EventType is the name of an event.
+            Example legal values:
+            	foo
+            	foo.bar
+            	foo.bar.baz
+            </xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:token">
+			<xsd:pattern value="(\i|\d|\-)+(\.(\i|\d|\-)+)*"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+
+	<xsd:simpleType name="EventTypes.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+			Custom datatype for the event attribute in SCXML based on xsd:token.
+			Example legal values:
+				*
+				foo
+				foo.bar
+				foo.*
+				foo.bar.*
+				foo bar baz
+				foo.bar bar.* baz.foo.*
+            </xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:token">
+			<xsd:pattern value="\.?\*|(\i|\d|\-)+(\.(\i|\d|\-)+)*(\.\*)?(\s(\i|\d|\-)+(\.(\i|\d|\-)+)*(\.\*)?)*"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+
+	<!-- Defines the  default CondLang datatype.        -->
+	<xsd:simpleType name="CondLang.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+		    Conditional language is expression 
+		    which must evaluate to Boolean True or False. 
+		    The expression language must define In(stateID) 
+		    as a valid expression.
+            </xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:string"/>
+	</xsd:simpleType>
+
+	<!-- Defines the  default LocLang datatype.         -->
+	<xsd:simpleType name="LocLang.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+	        Location language is expression
+		    identifying a location in the datamodel.  
+	        </xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:string"/>
+	</xsd:simpleType>
+
+	<!-- Defines the default ValueLang datatype.       -->
+	<xsd:simpleType name="ValueLang.datatype">
+		<xsd:annotation>
+			<xsd:documentation>
+		    Value language is expression
+		    return a value.
+            </xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:string"/>
+	</xsd:simpleType>
+</xsd:schema>

+ 16 - 16
test/scxml/tests/test144.txml

@@ -5,23 +5,23 @@ 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"/>
+
+  <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=""/> 
+    <transition event="foo" target="s1"/>
+    <transition event="*" conf:targetfail=""/>
+
   </state>
-  
-   <conf:pass/>
-   <conf:fail/>
+
+  <state id="s1">
+    <transition event="bar" conf:targetpass=""/>
+    <transition event="*" conf:targetfail=""/> 
+  </state>
+
+  <conf:pass/>
+  <conf:fail/>
 
 </scxml>

+ 10 - 0
test/scxml/transform.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+
+cd tests
+mkdir -p transformed
+
+for FILE in `find . -type f -name '*.txml'`
+do
+
+  xsltproc -o transformed/$FILE ../txml_to_sccd.xsl $FILE 
+done

+ 40 - 0
test/scxml/txml_to_sccd.xsl

@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<xsl:stylesheet
+    version="1.0"
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:scxml="http://www.w3.org/2005/07/scxml"
+    xmlns:conf="http://www.w3.org/2005/scxml-conformance"
+    xmlns="msdl.uantwerpen.be/sccd">
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+    <diagram>
+      <description>
+        <xsl:value-of select="/comment()"/>
+      </description>
+      <class name="Class1" default="true">
+        <xsl:apply-templates select="scxml:scxml"/>
+      </class>
+    </diagram>
+  </xsl:template>
+
+  <xsl:template match="/scxml:scxml">
+    <scxml initial="{@initial}">
+      <xsl:for-each select="scxml:state">
+        <state id="{@id}">
+        </state>
+      </xsl:for-each>
+      <xsl:for-each select="scxml:onentry">
+        <onentry>
+        </onentry>
+      </xsl:for-each>
+    </scxml>
+  </xsl:template>
+
+  <xsl:template match="scxml:state|scxml:scxml">
+  </xsl:template>
+
+<!--   <xsl:template match="onentry|onexit">
+
+  </xsl:template>
+ --></xsl:stylesheet>

+ 3 - 2
test/semantics/big_step_maximality/00_take_one.xml

@@ -6,10 +6,11 @@
 	<description>
 		Take One-semantics: Each big step, only one transition can be made (per orthogonal component).
 	</description>
-	<inport name="in"/>
 	<outport name="out"/>
 	<class name="c" default="true">
-		<scxml big_step_maximality="take_one" initial="a">
+		<scxml initial="a"
+			big_step_maximality="take_one"
+			internal_event_lifeline="queue">
 			<state id="a">
 				<onentry>
 					<raise event="entered_a" port="out"/>

+ 3 - 2
test/semantics/big_step_maximality/01_take_many.xml

@@ -6,10 +6,11 @@
 	<description>
 		Take Many-semantics: A big step doesn't end until there are no more enabled transitions.
 	</description>
-	<inport name="in"/>
 	<outport name="out"/>
 	<class name="c" default="true">
-		<scxml initial="a" big_step_maximality="take_many">
+		<scxml initial="a"
+			big_step_maximality="take_many"
+			internal_event_lifeline="queue">
 			<state id="a">
 				<onentry>
 					<raise event="entered_a" port="out"/>

+ 3 - 2
test/semantics/big_step_maximality/10_orthogonal_take_one.xml

@@ -6,10 +6,11 @@
 	<description>
 		Take One-semantics: Each big step, a transition in each orthogonal component is made.
 	</description>
-	<inport name="in"/>
 	<outport name="out"/>
 	<class name="c" default="true">
-		<scxml big_step_maximality="take_one">
+		<scxml
+			big_step_maximality="take_one"
+			internal_event_lifeline="queue">
 			<parallel id="p">
 				<state id="o0" initial="sa">
 					<state id="sa">

+ 6 - 4
test/semantics/big_step_maximality/11_orthogonal_take_many.xml

@@ -5,11 +5,13 @@
 	name="take_one">
 	<description>
 		Take Many-semantics: In both components, transitions keep firing until there are no more enabled transitions.
+		Updated Feb 2020: order of expected events in a slot shouldn't matter
 	</description>
-	<inport name="in"/>
 	<outport name="out"/>
 	<class name="c" default="true">
-		<scxml big_step_maximality="take_many">
+		<scxml
+			big_step_maximality="take_many"
+			internal_event_lifeline="queue">
 			<parallel id="p">
 				<state id="o0" initial="sa">
 					<state id="sa">
@@ -61,10 +63,10 @@
 			</slot>
 			<slot>
 				<!-- big step -->
+				<event name="entered_sf" port="out"/>
 				<event name="entered_sb" port="out"/>
-				<event name="entered_se" port="out"/>
 				<event name="entered_sc" port="out"/>
-				<event name="entered_sf" port="out"/>
+				<event name="entered_se" port="out"/>
 			</slot>
 		</expected>
 	</test>

+ 13 - 18
test/semantics/event_lifeline/event_consuming_whole.xml

@@ -6,13 +6,14 @@
     <description>
         Testing event consuming.
     </description>
-    <inport name="test_input" />
     <outport name="test_output" />
     <class name="Class1" default="true">
         <relationships>
             <association class="Class2" name="to_Class2" />
         </relationships>
-        <scxml initial="initial" input_event_lifeline="whole">
+        <scxml initial="initial"
+            big_step_maximality="take_one"
+            input_event_lifeline="whole">
             <state id="initial">
                 <onentry>
                     <raise event="create_instance" scope="cd">
@@ -70,22 +71,16 @@
         </scxml>
     </class>
     <test>
-       <expected>
-           <slot>
-               <event name="enter_one" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="exit_one" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_two" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="exit_two" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_three" port="test_output"/>
-           </slot>
+        <expected>
+            <slot>
+                <!-- Class1 initialization -->
+                <event name="enter_one" port="test_output"/>
+            </slot>
+            <slot>
+                <!-- Class1 transition to 'two' -->
+                <event name="exit_one" port="test_output"/>
+                <event name="enter_two" port="test_output"/>
+            </slot>
         </expected>
     </test>
 </diagram>

+ 88 - 0
test/semantics/event_lifeline/41_event_consuming_whole_take_many.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" ?>
+<diagram
+    xmlns="msdl.uantwerpen.be/sccd"
+    author="Simon Van Mierlo"
+    name="TestEventConsumingWhole">
+    <description>
+        Testing event consuming.
+    </description>
+    <outport name="test_output" />
+    <class name="Class1" default="true">
+        <relationships>
+            <association class="Class2" name="to_Class2" />
+        </relationships>
+        <scxml initial="initial"
+            big_step_maximality="take_many"
+            input_event_lifeline="whole">
+            <state id="initial">
+                <onentry>
+                    <raise event="create_instance" scope="cd">
+                        <parameter expr="'to_Class2'" />
+                    </raise>
+                </onentry>
+                <transition event="instance_created" target="../one">
+                    <parameter name="link_name" />
+                    <raise event="start_instance" scope="cd">
+                        <parameter expr="link_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="one">
+                <onentry>
+                    <raise event="enter_one" port="test_output" />
+                </onentry>
+                <onexit>
+                    <raise event="exit_one" port="test_output" />
+                </onexit>
+                <transition event="A" target="../two" cond="0" />
+                <transition event="B" target="../two" />
+            </state>
+            <state id="two">
+                <onentry>
+                    <raise event="enter_two" port="test_output" />
+                </onentry>
+                <onexit>
+                    <raise event="exit_two" port="test_output" />
+                </onexit>
+                <transition event="B" target="../three" />
+            </state>
+            <state id="three">
+                <onentry>
+                    <raise event="enter_three" port="test_output" />
+                </onentry>
+                <onexit>
+                    <raise event="exit_three" port="test_output" />
+                </onexit>
+            </state>
+        </scxml>
+    </class>
+    <class name="Class2">
+        <relationships>
+            <association class="Class1" name="parent" />
+        </relationships>
+        <scxml initial="initial">
+            <state id="initial">
+                <transition target="../final">
+                    <raise event="A" target="'parent'" />
+                    <raise event="B" target="'parent'" />
+                </transition>
+            </state>
+            <state id="final" />
+        </scxml>
+    </class>
+    <test>
+        <expected>
+            <slot>
+                <!-- Class1 initialization -->
+                <event name="enter_one" port="test_output"/>
+            </slot>
+            <slot>
+                <!-- Class1 transition to 'two' and 'three' -->
+                <event name="exit_one" port="test_output"/>
+                <event name="enter_two" port="test_output"/>
+                <event name="exit_two" port="test_output"/>
+                <event name="enter_three" port="test_output"/>
+            </slot>
+        </expected>
+    </test>
+</diagram>

+ 8 - 8
test/semantics/original_semantics/after.xml

@@ -1,8 +1,8 @@
 <?xml version="1.0" ?>
 <diagram
-	xmlns="msdl.uantwerpen.be/sccd"
-	author="Glenn De Jonghe"
-	name="TestAfter">
+    xmlns="msdl.uantwerpen.be/sccd"
+    author="Glenn De Jonghe"
+    name="TestAfter">
     <description>
         Used for testing the AFTER event.
     </description>
@@ -17,7 +17,7 @@
                 </state>
                 <state id="state_2">
                     <onentry>
-	                   <raise event="in_state_2" port="test_output" />
+                       <raise event="in_state_2" port="test_output" />
                     </onentry>
                 </state>
                 <state id="state_3">
@@ -29,10 +29,10 @@
         </scxml>
     </class>
     <test>
-       <expected>
-           <slot>
-               <event name="in_state_2" port="test_output"/>
-           </slot>
+        <expected>
+            <slot>
+                <event name="in_state_2" port="test_output"/>
+            </slot>
         </expected>
     </test>
 </diagram>

+ 0 - 3
test/semantics/original_semantics/associate_event.xml

@@ -43,9 +43,6 @@
     <class name="Class2" default="false">
         <scxml>
             <state id="start">
-                <onentry>
-                	<log>started</log>
-                </onentry>
                 <transition event="hello" target=".">
                     <raise port="test_output" event="second_working" />
                 </transition>

+ 4 - 1
test/semantics/original_semantics/correct_duplicate_state_id.xml

@@ -18,5 +18,8 @@
             </state>
         </scxml>
     </class>
-    <test/> <!-- Should just compile without a thrown exception. -->
+    <test>
+        <expected/>
+         <!-- Should just compile without a thrown exception. -->
+    </test>
 </diagram>

+ 114 - 117
test/semantics/original_semantics/enter_exit_hierarchy.xml

@@ -3,122 +3,119 @@
 	xmlns="msdl.uantwerpen.be/sccd"
 	author="Glenn De Jonghe"
 	name="TestEnterExitHierarchy">
-    <description>
-        Testing the enter and exit hierarchy.
-    </description>
-    <inport name="test_input" />
-    <outport name="test_output" />
-    <class name="Class1" default="true">
-        <scxml initial="outside">
-            <state id="outside">
-                <transition port="test_input" event="to_composite" target="/composite"/>
-                <transition port="test_input" event="to_inner3" target="/composite/state2/inner3"/>
-                <transition port="test_input" event="to_inner4" target="/composite/state2/inner4"/>
-            </state>
-            <state id="composite" initial="state1">
-                
-                <state id="state1" initial="inner1">
-                    <onentry>
-                        <raise port="test_output" event="enter_state1" />
-                    </onentry>
-                    <onexit>
-                        <raise port="test_output" event="exit_state1" />
-                    </onexit>
-                    <state id="inner1">
-                        <onentry>
-                            <raise port="test_output" event="enter_inner1" />
-                        </onentry>
-                        <onexit>
-                            <raise port="test_output" event="exit_inner1" />
-                        </onexit>
-                        <transition port="test_input" event="to_inner2" target="../inner2"/>
-                    </state>
-                    <state id="inner2">
-                        <onentry>
-                            <raise port="test_output" event="enter_inner2" />
-                        </onentry>
-                        <onexit>
-                            <raise port="test_output" event="exit_inner2" />
-                        </onexit>
-                    </state>
-                </state>
-                
+  <description>
+    Testing the enter and exit hierarchy.
+  </description>
+  <inport name="in" />
+  <outport name="out" />
+  <class name="Class1" default="true">
+    <scxml initial="outside">
 
-                <state id="state2" initial="inner3">
-                    <onentry>
-                        <raise port="test_output" event="enter_state2" />
-                    </onentry>
-                    <onexit>
-                        <raise port="test_output" event="exit_state2" />
-                    </onexit>
-                    <state id="inner3">
-                        <onentry>
-                            <raise port="test_output" event="enter_inner3" />
-                        </onentry>
-                        <onexit>
-                            <raise port="test_output" event="exit_inner3" />
-                        </onexit>
-                    </state>
-                    <state id="inner4">
-                        <onentry>
-                            <raise port="test_output" event="enter_inner4" />
-                        </onentry>
-                        <onexit>
-                            <raise port="test_output" event="exit_inner4" />
-                        </onexit>
-                    </state>
-                </state>
-                
-                <transition port="test_input" event="to_outside" target="/outside"/>
-            </state>
-        </scxml>
-    </class>
-    <test>
-        <input>
-            <event name="to_composite" port="test_input" time="0.0"/>
-            <event name="to_inner2" port="test_input" time="0.0"/>
-            <event name="to_outside" port="test_input" time="0.0"/>
-            <event name="to_inner3" port="test_input" time="0.0"/>
-            <event name="to_outside" port="test_input" time="0.0"/>
-            <event name="to_inner4" port="test_input" time="0.0"/>
-        </input>
-       <expected>
-           <slot>
-               <event name="enter_state1" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_inner1" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="exit_inner1" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_inner2" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="exit_inner2" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="exit_state1" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_state2" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_inner3" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="exit_inner3" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="exit_state2" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_state2" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_inner4" port="test_output"/>
-           </slot>
-        </expected>
-    </test>
+      <state id="outside">
+        <transition port="in" event="to_composite" target="/composite"/>
+        <transition port="in" event="to_inner3" target="/composite/state2/inner3"/>
+        <transition port="in" event="to_inner4" target="/composite/state2/inner4"/>
+      </state>
+
+      <state id="composite" initial="state1">
+
+        <state id="state1" initial="inner1">
+          <onentry>
+            <raise port="out" event="enter_state1" />
+          </onentry>
+          <onexit>
+            <raise port="out" event="exit_state1" />
+          </onexit>
+          <state id="inner1">
+            <onentry>
+              <raise port="out" event="enter_inner1" />
+            </onentry>
+            <onexit>
+              <raise port="out" event="exit_inner1" />
+            </onexit>
+            <transition port="in" event="to_inner2" target="../inner2"/>
+          </state>
+          <state id="inner2">
+            <onentry>
+              <raise port="out" event="enter_inner2" />
+            </onentry>
+            <onexit>
+              <raise port="out" event="exit_inner2" />
+            </onexit>
+          </state>
+        </state>
+
+        <state id="state2" initial="inner3">
+          <onentry>
+            <raise port="out" event="enter_state2" />
+          </onentry>
+          <onexit>
+            <raise port="out" event="exit_state2" />
+          </onexit>
+          <state id="inner3">
+            <onentry>
+              <raise port="out" event="enter_inner3" />
+            </onentry>
+            <onexit>
+              <raise port="out" event="exit_inner3" />
+            </onexit>
+          </state>
+          <state id="inner4">
+            <onentry>
+              <raise port="out" event="enter_inner4" />
+            </onentry>
+            <onexit>
+              <raise port="out" event="exit_inner4" />
+            </onexit>
+          </state>
+        </state>
+
+        <transition port="in" event="to_outside" target="/outside"/>
+      </state>
+
+    </scxml>
+  </class>
+  <test>
+    <input>
+      <event name="to_composite" port="in" time="0.0"/>
+      <event name="to_inner2" port="in" time="0.0"/>
+      <event name="to_outside" port="in" time="0.0"/>
+      <event name="to_inner3" port="in" time="0.0"/>
+      <event name="to_outside" port="in" time="0.0"/>
+      <event name="to_inner4" port="in" time="0.0"/>
+    </input>
+    
+    <expected>
+     <slot>
+      <!-- big step with input 'to_composite' -->
+      <event name="enter_state1" port="out"/>
+      <event name="enter_inner1" port="out"/>
+    </slot>
+    <slot>
+      <!-- big step with input 'to_inner2' -->
+      <event name="exit_inner1" port="out"/>
+      <event name="enter_inner2" port="out"/>
+    </slot>
+    <slot>
+      <!-- big step with input 'to_outside' -->
+      <event name="exit_inner2" port="out"/>
+      <event name="exit_state1" port="out"/>
+    </slot>
+    <slot>
+      <!-- big step with input 'to_inner3' -->
+      <event name="enter_state2" port="out"/>
+      <event name="enter_inner3" port="out"/>
+    </slot>
+    <slot>
+      <!-- big step with input 'to_outside' -->
+      <event name="exit_inner3" port="out"/>
+      <event name="exit_state2" port="out"/>
+    </slot>
+    <slot>
+      <!-- big step with input 'to_inner4' -->
+      <event name="enter_state2" port="out"/>
+      <event name="enter_inner4" port="out"/>
+    </slot>
+  </expected>
+</test>
 </diagram>

+ 31 - 35
test/semantics/original_semantics/event_consuming.xml

@@ -6,86 +6,82 @@
     <description>
         Testing event consuming.
     </description>
-    <inport name="test_input" />
-    <outport name="test_output" />
+    <inport name="in"/>
+    <outport name="out"/>
     <class name="Class1" default="true">
         <relationships>
-            <association class="Class2" name="to_Class2" />
+            <association class="Class2" name="to_Class2"/>
         </relationships>
         <scxml initial="initial">
             <state id="initial">
                 <onentry>
                     <raise event="create_instance" scope="cd">
-                        <parameter expr="'to_Class2'" />
+                        <parameter expr="'to_Class2'"/>
                     </raise>
                 </onentry>
                 <transition event="instance_created" target="../one">
-                    <parameter name="link_name" />
+                    <parameter name="link_name"/>
                     <raise event="start_instance" scope="cd">
-                        <parameter expr="link_name" />
+                        <parameter expr="link_name"/>
                     </raise>
                 </transition>
             </state>
             <state id="one">
                 <onentry>
-                    <raise event="enter_one" port="test_output" />
+                    <raise event="enter_one" port="out"/>
                 </onentry>
                 <onexit>
-                    <raise event="exit_one" port="test_output" />
+                    <raise event="exit_one" port="out"/>
                 </onexit>
-                <transition event="A" target="../two" cond="0" />
-                <transition event="B" target="../two" />
+                <transition event="A" target="../two" cond="0"/>
+                <transition event="B" target="../two"/>
             </state>
             <state id="two">
                 <onentry>
-                    <raise event="enter_two" port="test_output" />
+                    <raise event="enter_two" port="out"/>
                 </onentry>
                 <onexit>
-                    <raise event="exit_two" port="test_output" />
+                    <raise event="exit_two" port="out"/>
                 </onexit>
-                <transition event="A" target="../three" />
+                <transition event="A" target="../three"/>
             </state>
             <state id="three">
                 <onentry>
-                    <raise event="enter_three" port="test_output" />
+                    <raise event="enter_three" port="out"/>
                 </onentry>
                 <onexit>
-                    <raise event="exit_three" port="test_output" />
+                    <raise event="exit_three" port="out"/>
                 </onexit>
             </state>
         </scxml>
     </class>
     <class name="Class2">
         <relationships>
-            <association class="Class1" name="parent" />
+            <association class="Class1" name="parent"/>
         </relationships>
         <scxml initial="initial">
             <state id="initial">
                 <transition target="../final">
-                    <raise event="B" target="'parent'" />
-                    <raise event="A" target="'parent'" />
+                    <raise event="B" target="'parent'"/>
+                    <raise event="A" target="'parent'"/>
                 </transition>
             </state>
-            <state id="final" />
+            <state id="final"/>
         </scxml>
     </class>
     <test>
-       <expected>
-           <slot>
-               <event name="enter_one" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="exit_one" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_two" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="exit_two" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="enter_three" port="test_output"/>
-           </slot>
+        <expected>
+            <slot>
+                <event name="enter_one" port="out"/>
+            </slot>
+            <slot>
+                <event name="exit_one" port="out"/>
+                <event name="enter_two" port="out"/>
+            </slot>
+            <slot>
+                <event name="exit_two" port="out"/>
+                <event name="enter_three" port="out"/>
+            </slot>
         </expected>
     </test>
 </diagram>

+ 0 - 2
test/semantics/original_semantics/event_consuming_2.xml

@@ -76,8 +76,6 @@
            </slot>
            <slot>
                <event name="exit_one" port="test_output"/>
-           </slot>
-           <slot>
                <event name="enter_two" port="test_output"/>
            </slot>
         </expected>

+ 32 - 30
test/semantics/original_semantics/history.xml

@@ -1,58 +1,60 @@
 <?xml version="1.0" ?>
 <diagram
-	xmlns="msdl.uantwerpen.be/sccd"
-	author="Glenn De Jonghe"
-	name="TestHistory">
+    xmlns="msdl.uantwerpen.be/sccd"
+    author="Glenn De Jonghe"
+    name="TestHistory">
     <description>
         Testing the History state.
     </description>
-    <inport name="test_input" />
-    <outport name="test_output" />
+    <inport name="in"/>
+    <outport name="out"/>
     <class name="Class1" default="true">
-        <scxml initial="composite_1">
+        <scxml initial="composite_1"
+            big_step_maximality="take_many">
             <state id="composite_1" initial="state_1">
                 <state id="state_1">
                     <onentry>
-                       <raise port="test_output" event="in_state_1" />
+                        <raise port="out" event="in_state_1"/>
                     </onentry>
-                    <transition port="test_input" event="to_state_2" target="../state_2"/>
+                    <transition port="in" event="to_state_2" target="../state_2"/>
                 </state>
                 <state id="state_2">
                     <onentry>
-	                   <raise port="test_output" event="in_state_2" />
+                        <raise port="out" event="in_state_2"/>
                     </onentry>
                 </state>
                 <history id="composite_history">
                     <transition target="../state_1"/>
                 </history>
-                <transition port="test_input" event="to_state_3" target="../state_3"/>
+                <transition port="in" event="to_state_3" target="../state_3"/>
             </state>
             <state id="state_3">
                 <onentry>
-                   <raise port="test_output" event="in_state_3" />
+                    <raise port="out" event="in_state_3"/>
                 </onentry>
                 <transition target="/composite_1/composite_history"/>
             </state>
         </scxml>
     </class>
     <test>
-    	<input>
-    		<event name="to_state_2" port="test_input" time="0.0"/>
-    		<event name="to_state_3" port="test_input" time="0.0"/>
-    	</input>
-	   <expected>
-	       <slot>
-	           <event name="in_state_1" port="test_output"/>
-	       </slot>
-           <slot>
-               <event name="in_state_2" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="in_state_3" port="test_output"/>
-           </slot>
-           <slot>
-               <event name="in_state_2" port="test_output"/>
-           </slot>
-	    </expected>
-	</test>
+        <input>
+            <event name="to_state_2" port="in" time="0.0"/>
+            <event name="to_state_3" port="in" time="0.0"/>
+        </input>
+        <expected>
+            <slot>
+                <!-- initialization -->
+                <event name="in_state_1" port="out"/>
+            </slot>
+            <slot>
+                <!-- big step with input 'to_state_2' -->
+                <event name="in_state_2" port="out"/>
+            </slot>
+            <slot>
+                <!-- big step with input 'to_state_3' -->
+                <event name="in_state_3" port="out"/>
+                <event name="in_state_2" port="out"/>
+            </slot>
+        </expected>
+    </test>
 </diagram>

+ 0 - 3
test/semantics/original_semantics/object_manager.xml

@@ -38,9 +38,6 @@
     <class name="Class2" default="false">
         <scxml>
             <state id="start">
-                <onentry>
-                	<log>started</log>
-                </onentry>
                 <transition event="hello" target=".">
                     <raise port="test_output" event="second_working" />
                 </transition>

+ 28 - 27
test/test.py

@@ -40,7 +40,7 @@ class PyTestCase(unittest.TestCase):
 
         module = importlib.import_module(os.path.join(BUILD_DIR, self.name).replace(os.path.sep, "."))
         inputs = module.Test.input_events
-        expected = module.Test.expected_events
+        expected = module.Test.expected_events # list of lists of Event objects
 
         controller = module.Controller(False)
 
@@ -48,12 +48,8 @@ class PyTestCase(unittest.TestCase):
             for i in inputs:
                 controller.addInput(Event(i.name, i.port, i.parameters), int(i.time_offset * 1000))
 
-        if not expected:
-            controller.start()
-            return
-
         output_ports = set()
-        expected_result = []
+        expected_result = [] # what happens here is basically a deep-copy of the list-of-lists, why?
         for s in expected:
             slot = []
             for event in s:
@@ -62,27 +58,33 @@ class PyTestCase(unittest.TestCase):
             if slot:
                 expected_result.append(slot)
 
-        output_listener = controller.addOutputListener(list(output_ports))
+        output_listener = controller.createOutputListener(list(output_ports))
 
         def check_output():
             # check output
-            for (slot_index, slot) in enumerate(expected_result, start=1) : 
-                for entry in slot:
-                    output_event = output_listener.fetch(0)
-                    self.assertNotEqual(output_event, None, "Not enough output events on selected ports while checking for event %s" % entry)
+            for (slot_index, slot) in enumerate(expected_result) : 
+                output_events = output_listener.fetch(0)
+                # print("slot:", slot_index, ", events: ", output_events)
+                # sort both expected and actual lists of events before comparing,
+                # in theory the set of events at the end of a big step is unordered
+                sort_events = lambda e: "%s.%s"%(e.port, e.name)
+                slot.sort(key=sort_events)
+                output_events.sort(key=sort_events)
+                self.assertEqual(len(slot), len(output_events), "Expected %d output events, instead got: %d" % (len(slot), len(output_events)))
+                for (expected, actual) in zip(slot, output_events):
                     matches = True
-                    if output_event.name != entry.name :
+                    if expected.name != actual.name :
                         matches = False
-                    if output_event.port != entry.port :
+                    if expected.port != actual.port :
                         matches = False
-                    compare_parameters = output_event.getParameters()
-                    if len(entry.parameters) != len(compare_parameters) :
+                    actual_parameters = actual.getParameters()
+                    if len(expected.parameters) != len(actual_parameters) :
                         matches = False
-                    for index in range(len(entry.parameters)) :
-                        if entry.parameters[index] !=  compare_parameters[index]:
+                    for index in range(len(expected.parameters)) :
+                        if expected.parameters[index] !=  actual_parameters[index]:
                             matches = False
 
-                    self.assertTrue(matches, self.src_file + ", expected results slot " + str(slot_index) + " mismatch. Expected " + str(entry) + ", but got " + str(output_event) +  " instead.") # no match found in the options
+                    self.assertTrue(matches, self.src_file + ", expected results slot " + str(slot_index) + " mismatch. Expected " + str(expected) + ", but got " + str(actual) +  " instead.") # no match found in the options
 
             # check if there are no extra events
             next_event = output_listener.fetch(0)
@@ -106,19 +108,18 @@ if __name__ == '__main__':
             already_have.add(path)
             src_files.append(path)
 
-    def add_file_or_dir(path):
-        if os.path.isdir(path):
+    for p in args.test:
+        if os.path.isdir(p):
             # recursively scan directories
-            for r, dirs, files in os.walk(path):
+            for r, dirs, files in os.walk(p):
+                files.sort()
                 for f in files:
                     if f.endswith('.xml'):
                         add_file(os.path.join(r,f))
-        elif os.path.isfile(path):
-            add_file(path)
-
-
-    for f in args.test:
-        add_file_or_dir(f)
+        elif os.path.isfile(p):
+            add_file(p)
+        else:
+            print("%s: not a file or a directory, skipped." % p)
 
     # src_files should now contain a list of XML files that need to be compiled an ran