Skip to content
This repository was archived by the owner on May 22, 2021. It is now read-only.

Commit 0676434

Browse files
committed
Tests + debug
1 parent 6b6cd09 commit 0676434

File tree

9 files changed

+217
-4
lines changed

9 files changed

+217
-4
lines changed

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
<groupId>rams</groupId>
77
<artifactId>scxml-to-fsm</artifactId>
88
<version>1.0-SNAPSHOT</version>
9+
<dependencies>
10+
<dependency>
11+
<groupId>junit</groupId>
12+
<artifactId>junit</artifactId>
13+
<version>4.12</version>
14+
<scope>test</scope>
15+
</dependency>
16+
</dependencies>
917

1018

1119
</project>

scxmltofsm.iml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@
1111
</content>
1212
<orderEntry type="inheritedJdk" />
1313
<orderEntry type="sourceFolder" forTests="false" />
14+
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
15+
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
1416
</component>
1517
</module>

src/main/java/stateMachine/AbstractStateMachine.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,41 @@ public abstract class AbstractStateMachine implements Serializable {
1313
protected List<State> stateList;
1414
protected State initState;
1515
protected State currentState;
16+
protected EventHandler eventHandler;
1617

1718
public AbstractStateMachine(){
19+
this.eventHandler = new EventHandler(this);
1820
this.stateList = new ArrayList<State>();
1921
}
2022

23+
public List<State> getStateList(){
24+
return this.stateList;
25+
}
26+
27+
public State getInitState(){
28+
return this.initState;
29+
}
30+
31+
public State getCurrentState(){
32+
return this.currentState;
33+
}
34+
2135
protected void init(){
2236
if(initState == null && stateList.size() != 0) {
2337
initState = stateList.get(0);
2438
}
2539
this.currentState = initState;
2640
}
2741

42+
public void start(){
43+
Thread t = new Thread(eventHandler);
44+
t.start();
45+
}
46+
47+
public void stop(){
48+
eventHandler.stop();
49+
}
50+
2851
public void notifyEvent(String event){
2952
this.currentState = this.currentState.notifyEvent(event);
3053
}
@@ -56,6 +79,7 @@ public void connectToEvent(String eventName, Callable callable){
5679
public void linkStates(){
5780
for(State state: this.stateList){
5881
for(Transition transition : state.getTransitions()){
82+
transition.setFrom(state);
5983
for(State state1 : this.stateList){
6084
if(transition.to().getId().equals(state1.getId())){
6185
transition.setTo(state1);

src/main/java/stateMachine/Event.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
public class Event implements Serializable {
1111
private String name;
1212
private List<Callable> callables;
13+
private Type type;
14+
15+
public enum Type {SEND, RAISE}
1316

1417
public Event(String name){
1518
this.name = name;
@@ -38,4 +41,8 @@ public int getDelay(){
3841
}
3942
return delay;
4043
}
44+
45+
public Type getType(){
46+
return this.type;
47+
}
4148
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package stateMachine;
2+
3+
import java.util.ArrayList;
4+
5+
/**
6+
* Created by Rami on 08/04/2017.
7+
*/
8+
public class EventHandler implements Runnable {
9+
10+
private ArrayList<Event> eventsStack;
11+
private AbstractStateMachine stateMachine;
12+
private boolean run;
13+
14+
public EventHandler(AbstractStateMachine stateMachine){
15+
this.eventsStack = new ArrayList<Event>();
16+
this.stateMachine = stateMachine;
17+
this.run = false;
18+
}
19+
20+
21+
public void run() {
22+
start();
23+
while(run){
24+
Event e = getNextEvent();
25+
if(e != null){
26+
e.trigger();
27+
}
28+
}
29+
}
30+
31+
public void stop(){
32+
this.run = false;
33+
}
34+
35+
public void start(){
36+
this.run = true;
37+
}
38+
39+
private Event getNextEvent(){
40+
Event e = null;
41+
for(int i = 0; i<eventsStack.size(); i++){
42+
if(eventsStack.get(i).getType().equals(Event.Type.SEND)){
43+
return eventsStack.remove(i);
44+
}
45+
}
46+
for(int i = 0; i<eventsStack.size(); i++){
47+
if(eventsStack.get(i).getType().equals(Event.Type.RAISE)){
48+
return eventsStack.remove(i);
49+
}
50+
}
51+
return null;
52+
}
53+
}

src/main/java/stateMachine/SCXMLToJava.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ public class SCXMLToJava {
1919

2020
private final String openInst = "{";
2121
private final String closeInst = "}";
22-
private final String packageHeader="package stateMachine;\n";
22+
private final String packageHeader="import stateMachine.*;\n";
2323
private final String messageHeader="/**\nGenerated By SCXMLToJava class\n**/\n";
2424
private final String classNameHeader="public class GStateMachine extends AbstractStateMachine" + openInst + "\n";
2525
private final String constructorHeader="public GStateMachine()" + openInst + "\n";
26-
26+
private final String fileName = "GStateMachine.java";
2727
private String javaCode;
2828

2929
private Document doc;
@@ -38,7 +38,7 @@ public SCXMLToJava(File scxmlDocument) throws ParserConfigurationException, IOEx
3838
public void generateJavaCode() throws IOException {
3939
String constructorBody = parseScxml(this.doc);
4040
this.javaCode = packageHeader + messageHeader + classNameHeader + constructorHeader + constructorBody + closeInst + closeInst;
41-
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("GStateMachine.java"), "utf-8"));
41+
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.fileName), "utf-8"));
4242
writer.write(this.javaCode);
4343
writer.flush();
4444
writer.close();
@@ -52,6 +52,7 @@ private String parseScxml(Document doc){
5252
result += parseState(init.getChildNodes().item(i));
5353
}
5454
}
55+
result += "super.linkStates();\n";
5556
result += "super.init();\n";
5657
return result;
5758
}
@@ -157,4 +158,8 @@ private String parseTransitionEventsTrigger(Element e){
157158
}
158159
return result;
159160
}
161+
162+
public File getJavaCodeFile(){
163+
return new File(this.fileName);
164+
}
160165
}

src/main/java/stateMachine/State.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class State implements Serializable {
1515
private List<Event> onEntry;
1616
private List<Event> onExit;
1717

18-
State(){
18+
public State(){
1919
this.id = "";
2020
this.isInit = false;
2121
this.transitions = new ArrayList<Transition>();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
2+
<state id="State1">
3+
<transition event="event1" target="State2" type="external"/>
4+
</state>
5+
<state id="State2">
6+
<transition event="event2" target="State1" type="external"/>
7+
</state>
8+
</scxml>
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package integration;
2+
import org.junit.Before;
3+
import org.junit.BeforeClass;
4+
import org.junit.Test;
5+
import org.xml.sax.SAXException;
6+
import stateMachine.AbstractStateMachine;
7+
import stateMachine.GStateMachine;
8+
import stateMachine.SCXMLToJava;
9+
import stateMachine.State;
10+
11+
import javax.tools.JavaCompiler;
12+
import javax.tools.ToolProvider;
13+
import javax.xml.parsers.ParserConfigurationException;
14+
import java.io.File;
15+
import java.io.IOException;
16+
import java.net.URL;
17+
import java.net.URLClassLoader;
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
21+
import static org.junit.Assert.assertEquals;
22+
23+
/**
24+
* Created by Rami on 08/04/2017.
25+
*/
26+
public class SimpleStateMachineTest {
27+
28+
static String ressourceDir = "src\\main\\resources\\";
29+
static String integrationTestDir = "integrationTests\\";
30+
static AbstractStateMachine stateMachine;
31+
32+
@BeforeClass
33+
public static void prepareEnv(){
34+
File scxml = new File(ressourceDir + integrationTestDir +"test1.scxml");
35+
try {
36+
SCXMLToJava builder = new SCXMLToJava(scxml);
37+
builder.generateJavaCode();
38+
File javaCode = builder.getJavaCodeFile();
39+
File root = javaCode.getAbsoluteFile().getParentFile();
40+
System.out.println(root);
41+
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
42+
compiler.run(null, System.out, System.err, javaCode.getPath());
43+
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{root.toURI().toURL()});
44+
Class<?> cls = Class.forName("GStateMachine", true, classLoader);
45+
stateMachine = (AbstractStateMachine) cls.newInstance();
46+
} catch (ParserConfigurationException e) {
47+
e.printStackTrace();
48+
} catch (IOException e) {
49+
e.printStackTrace();
50+
} catch (SAXException e) {
51+
e.printStackTrace();
52+
} catch (IllegalAccessException e) {
53+
e.printStackTrace();
54+
} catch (InstantiationException e) {
55+
e.printStackTrace();
56+
} catch (ClassNotFoundException e) {
57+
e.printStackTrace();
58+
}
59+
}
60+
61+
62+
@Test
63+
public void testInitState(){
64+
//Test if the proper state has been set to initial (State1 without prior indication)
65+
assertEquals(this.stateMachine.getInitState().getId(), "State1");
66+
67+
//Test if initial state is current state if we do not start the machine
68+
assertEquals(this.stateMachine.getInitState(), this.stateMachine.getCurrentState());
69+
}
70+
71+
@Test
72+
public void testNbOfStates(){
73+
assertEquals(this.stateMachine.getStateList().size(), 2);
74+
}
75+
76+
@Test
77+
public void testStatesNames(){
78+
List<State> states = this.stateMachine.getStateList();
79+
List<State> expected = new ArrayList<State>();
80+
expected.add(new State("State1"));
81+
expected.add(new State("State2"));
82+
for(int i = 0; i < states.size(); i++){
83+
assertEquals(states.get(i).getId(), expected.get(i).getId());
84+
}
85+
}
86+
87+
@Test
88+
public void testNBOfTransitions(){
89+
List<State> states = this.stateMachine.getStateList();
90+
for(State state: states){
91+
assertEquals(state.getTransitions().size(), 1);
92+
}
93+
}
94+
95+
@Test
96+
public void testTransition(){
97+
List<State> states = this.stateMachine.getStateList();
98+
System.out.println(states.get(0).getTransitions().get(0));
99+
assertEquals(states.get(0).getTransitions().get(0).from(), states.get(0));
100+
assertEquals(states.get(0).getTransitions().get(0).to(), states.get(1));
101+
102+
assertEquals(states.get(1).getTransitions().get(0).from(), states.get(1));
103+
assertEquals(states.get(1).getTransitions().get(0).to(), states.get(0));
104+
105+
}
106+
}

0 commit comments

Comments
 (0)