Преглед изворни кода

fixed #252 : Check validation of pseudo states

terfloth@itemis.de пре 14 година
родитељ
комит
27a4ef3a8f

+ 78 - 0
plugins/org.yakindu.sct.model.statechart.test/src/org/yakindu/sct/model/statechart/test/StatechartBaseValidationTest.java

@@ -17,6 +17,7 @@ import junit.framework.TestCase;
 import org.eclipse.emf.common.util.BasicDiagnostic;
 import org.eclipse.emf.common.util.Diagnostic;
 import org.yakindu.model.sct.statechart.Entry;
+import org.yakindu.model.sct.statechart.EntryKind;
 import org.yakindu.model.sct.statechart.FinalState;
 import org.yakindu.model.sct.statechart.Region;
 import org.yakindu.model.sct.statechart.State;
@@ -136,6 +137,7 @@ public class StatechartBaseValidationTest extends TestCase {
 	public void testValidState() {
 		prepareStateTest();
 		Entry entry = factory.createEntry();
+		region.getVertices().add(entry);
 		createTransition(entry, state);
 				
 		assertTrue(validator.validate(state,  diagnostics, new HashMap<Object,Object>()));
@@ -143,6 +145,82 @@ public class StatechartBaseValidationTest extends TestCase {
 	}
 
 	
+	/**
+	 * An initial entry should have no incoming transition
+	 */
+	public void testInitialEntryWithIncomingTransition() {
+		prepareStateTest();
+		
+		Entry entry = factory.createEntry();
+		region.getVertices().add(entry);
+		createTransition(state, entry);
+
+		assertEquals(EntryKind.INITIAL, entry.getKind());
+		assertFalse(validator.validate(entry,  diagnostics, new HashMap<Object,Object>()));		
+		assertWarning(diagnostics, ISSUE_INITIAL_ENTRY_WITH_IN_TRANS);
+	}
+	
+	
+	/**
+	 * A valid entry should have No issues
+	 */
+	public void testValidInitialEntry() {
+		prepareStateTest();
+		
+		Entry entry = factory.createEntry();
+		region.getVertices().add(entry);
+		createTransition(entry, state);
+
+		assertEquals(EntryKind.INITIAL, entry.getKind());
+		assertTrue(validator.validate(entry,  diagnostics, new HashMap<Object,Object>()));		
+		assertIssueCount(diagnostics, 0);
+	}
+	
+	
+	/**
+	 * An initial entry should have an outgoing transition
+	 */
+	public void testInitialEntryWithoutOutTransition() {
+		prepareStateTest();
+		
+		Entry entry = factory.createEntry();
+		region.getVertices().add(entry);
+		
+		assertEquals(EntryKind.INITIAL, entry.getKind());
+		assertFalse(validator.validate(entry,  diagnostics, new HashMap<Object,Object>()));		
+		assertWarning(diagnostics, ISSUE_INITIAL_ENTRY_WITHOUT_OUT_TRANS);
+	}
+	
+	/**
+	 * An entry should not have more than one outgoing transition
+	 */
+	public void testEntryMultipleOutTransition() {
+		prepareStateTest();
+		
+		Entry entry = factory.createEntry();
+		region.getVertices().add(entry);
+		createTransition(entry,	state);
+		createTransition(entry, state);
+		
+		assertEquals(EntryKind.INITIAL, entry.getKind());
+		assertFalse(validator.validate(entry,  diagnostics, new HashMap<Object,Object>()));		
+		assertError(diagnostics, ISSUE_ENTRY_WITH_MULTIPLE_OUT_TRANS);
+		
+		entry.setKind(EntryKind.SHALLOW_HISTORY);
+		
+		diagnostics = new BasicDiagnostic();
+		assertFalse(validator.validate(entry,  diagnostics, new HashMap<Object,Object>()));		
+		assertError(diagnostics, ISSUE_ENTRY_WITH_MULTIPLE_OUT_TRANS);
+		
+		entry.setKind(EntryKind.DEEP_HISTORY);
+		
+		diagnostics = new BasicDiagnostic();
+		assertFalse(validator.validate(entry,  diagnostics, new HashMap<Object,Object>()));		
+		assertError(diagnostics, ISSUE_ENTRY_WITH_MULTIPLE_OUT_TRANS);
+		
+
+	}
+	
 	
 	/**
 	 * A final state should have at least one incoming transition.

+ 33 - 20
plugins/org.yakindu.sct.model.statechart/src/org/yakindu/model/sct/statechart/util/StatechartValidator.java

@@ -57,7 +57,9 @@ public class StatechartValidator extends EObjectValidator {
 	public static final String ISSUE_NODE_NOT_REACHABLE = "Node is not reachable due to missing incoming transition.";
 	public static final String ISSUE_FINAL_STATE_OUTGOING_TRANSITION = "A final state should have no outgoing transition.";
 	public static final String ISSUE_STATE_WITHOUT_OUTGOING_TRANSITION = "A state should have at least one outgoing transition.";
-
+	public static final String ISSUE_INITIAL_ENTRY_WITH_IN_TRANS = "Initial entry should have no incoming transition.";
+	public static final String ISSUE_INITIAL_ENTRY_WITHOUT_OUT_TRANS = "Initial entry should have a single outgoing transition";
+	public final static String ISSUE_ENTRY_WITH_MULTIPLE_OUT_TRANS = "Entries must not have more than one outgoing transition";
 	/**
 	 * <!-- begin-user-doc --> <!-- end-user-doc -->
 	 * @generated
@@ -232,7 +234,12 @@ public class StatechartValidator extends EObjectValidator {
 		if (vertex.getIncomingTransitions().size() == 0 && !(vertex instanceof Entry)) {
 			return error(vertex, diagnostics, ISSUE_NODE_NOT_REACHABLE);
 		}
+
+		if (vertex.getIncomingTransitions().size() > 0 && vertex instanceof Entry && ((Entry)vertex).getKind().equals(EntryKind.INITIAL)) {
+			return warning(vertex, diagnostics, ISSUE_INITIAL_ENTRY_WITH_IN_TRANS);
+		}
 		
+
 		return true;
 	}
 
@@ -245,14 +252,20 @@ public class StatechartValidator extends EObjectValidator {
 	public boolean validateVertex_OutgoingTransitionCount(Vertex vertex,
 			DiagnosticChain diagnostics, Map<Object, Object> context) {
 
-//		if (vertex.getOutgoingTransitions().size() == 0 && !(vertex instanceof FinalState)) {
-//			return warning(vertex, diagnostics, ISSUE_STATE_WITHOUT_OUTGOING_TRANSITION);
-//		} 
 		
 		if ((vertex.getOutgoingTransitions().size() > 0) && (vertex instanceof FinalState)) {
 			return warning(vertex, diagnostics, ISSUE_FINAL_STATE_OUTGOING_TRANSITION);
 		}
 		
+		if (vertex.getOutgoingTransitions().size() == 0 && vertex instanceof Entry && ((Entry)vertex).getKind().equals(EntryKind.INITIAL)) {
+			return warning(vertex, diagnostics, ISSUE_INITIAL_ENTRY_WITHOUT_OUT_TRANS);
+		} 
+
+		if (vertex.getOutgoingTransitions().size() > 1 && vertex instanceof Entry) {
+			return error(vertex, diagnostics, ISSUE_ENTRY_WITH_MULTIPLE_OUT_TRANS);
+		} 
+
+
 		return true;
 	}
 
@@ -295,22 +308,22 @@ public class StatechartValidator extends EObjectValidator {
 	public boolean validateRegion_ExactlyOneInitialState(Region region,
 			DiagnosticChain diagnostics, Map<Object, Object> context) {
 
-		int entryCount = 0;
-		EList<Vertex> vertices = region.getVertices();
-		for (Vertex vertex : vertices) {
-			if (vertex instanceof Entry) {
-				entryCount++;
-			}
-		}
-		if (entryCount != 1) {
-			if (diagnostics != null) {
-				diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING,
-						DIAGNOSTIC_SOURCE, 0,
-						"A region must contain exactly one initial state!",
-						new Object[] { region }));
-			}
-			return false;
-		}
+//		int entryCount = 0;
+//		EList<Vertex> vertices = region.getVertices();
+//		for (Vertex vertex : vertices) {
+//			if (vertex instanceof Entry) {
+//				entryCount++;
+//			}
+//		}
+//		if (entryCount != 1) {
+//			if (diagnostics != null) {
+//				diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING,
+//						DIAGNOSTIC_SOURCE, 0,
+//						"A region must contain exactly one initial state!",
+//						new Object[] { region }));
+//			}
+//			return false;
+//		}
 		return true;
 	}
 

+ 4 - 5
plugins/org.yakindu.sct.statechart.diagram/src/org/yakindu/sct/statechart/diagram/commands/CreateTransitionCommand.java

@@ -54,11 +54,10 @@ public class CreateTransitionCommand extends EditElementCommand {
 	}
 
 	private boolean checkConstraints() {
-		if (source instanceof FinalState)
-			return false;
-		if (target instanceof Entry)
-			return false;
-//FIXME
+//		if (source instanceof FinalState)
+//			return false;
+//		if (target instanceof Entry)
+//			return false;
 //		if (source instanceof HistoryState)
 //			return false;
 //		if (source instanceof InitialState && ((InitialState) source).getOutgoingTransitions().size() > 0)