/**
* Copyright (c) 2012 committers of YAKINDU and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
* Contributors:
* committers of YAKINDU - initial API and implementation
*
*/
package org.yakindu.sct.model.stext.resource.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.xtext.resource.XtextSyntaxDiagnostic;
import org.eclipse.xtext.util.CancelIndicator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.yakindu.base.expressions.expressions.ElementReferenceExpression;
import org.yakindu.base.expressions.expressions.ExpressionsFactory;
import org.yakindu.base.expressions.expressions.IntLiteral;
import org.yakindu.base.expressions.expressions.PrimitiveValueExpression;
import org.yakindu.base.types.Declaration;
import org.yakindu.base.types.Event;
import org.yakindu.sct.model.sgraph.SGraphFactory;
import org.yakindu.sct.model.sgraph.Scope;
import org.yakindu.sct.model.sgraph.State;
import org.yakindu.sct.model.sgraph.Statechart;
import org.yakindu.sct.model.sgraph.Transition;
import org.yakindu.sct.model.sgraph.util.ContextElementAdapter;
import org.yakindu.sct.model.sgraph.util.ContextElementAdapter.IContextElementProvider;
import org.yakindu.sct.model.stext.resource.StextResource;
import org.yakindu.sct.model.stext.stext.EventDefinition;
import org.yakindu.sct.model.stext.stext.ExitEvent;
import org.yakindu.sct.model.stext.stext.InternalScope;
import org.yakindu.sct.model.stext.stext.LocalReaction;
import org.yakindu.sct.model.stext.stext.ReactionTrigger;
import org.yakindu.sct.model.stext.stext.RegularEventSpec;
import org.yakindu.sct.model.stext.stext.StextFactory;
import org.yakindu.sct.model.stext.stext.TimeEventSpec;
import org.yakindu.sct.model.stext.stext.TimeEventType;
import org.yakindu.sct.model.stext.stext.TimeUnit;
import org.yakindu.sct.model.stext.ui.internal.STextActivator;
import org.yakindu.sct.test.models.SCTUnitTestModels;
import com.google.inject.Injector;
/**
*
* @author andreas muelder - Initial contribution and API
*
*/
public class SCTResourceTest {
private StextFactory stextFac = StextFactory.eINSTANCE;
private ExpressionsFactory expFac = ExpressionsFactory.eINSTANCE;
private StextResource res;
@Before
public void setUp() throws Exception {
Injector injector = STextActivator.getInstance().getInjector(STextActivator.ORG_YAKINDU_SCT_MODEL_STEXT_STEXT);
ResourceSet resourceSet = new ResourceSetImpl();
res = new StextResource(URI.createURI("test.test"));
res.eAdapters().add(new ContextElementAdapter(new IContextElementProvider() {
public EObject getContextObject() {
return res.getContents().get(0);
}
}));
resourceSet.getResources().add(res);
injector.injectMembers(res);
}
@After
public void tearDown() throws Exception {
res = null;
}
@Test
public void testFragments() throws Exception {
SCTUnitTestModels models = new SCTUnitTestModels();
List<Statechart> originalStatecharts = models.loadAllStatecharts();
List<Statechart> targetStatecharts = models.loadAllStatecharts();
for (int i = 0; i < originalStatecharts.size(); i++) {
Statechart statechart = originalStatecharts.get(i);
Statechart targetStatechart = targetStatecharts.get(i);
Resource targetResource = targetStatechart.eResource();
assertTrue(statechart != targetStatechart);
assertTrue(EcoreUtil.equals(statechart, targetStatechart));
TreeIterator<EObject> allContents = EcoreUtil.getAllContents(statechart.eResource(), true);
while (allContents.hasNext()) {
EObject next = allContents.next();
String fragment = EcoreUtil.getURI(next).fragment();
EObject targetObject = targetResource.getEObject(fragment);
assertNotNull("Could not resolve fragment " + fragment + " for EObject " + next + "in statechart "
+ statechart.getName(), targetObject);
assertTrue(EcoreUtil.equals(next, targetObject));
}
}
}
@Test
public void testStatechartParsing() {
Statechart statechart = createStatechart("internal: event Event1");
assertEquals(0, statechart.getScopes().size());
res.getContents().add(statechart);
assertEquals(1, statechart.getScopes().size());
Scope scope = statechart.getScopes().get(0);
assertTrue(scope instanceof InternalScope);
EList<Declaration> declarations = ((InternalScope) scope).getDeclarations();
Declaration declaration = declarations.get(0);
assertTrue(declaration instanceof EventDefinition);
assertEquals("" + res.getSyntaxDiagnostics(), 0, res.getSyntaxDiagnostics().size());
}
@Test
public void testTransitionParsing() throws Exception {
Transition transition = createTransition("after 10 s [true] / 3 * 3");
assertNull(transition.getTrigger());
assertNull(transition.getEffect());
res.getContents().add(transition);
assertNotNull(transition.getTrigger());
assertNotNull(transition.getEffect());
}
@Test
public void testStateParsing() throws Exception {
State state = createState("entry / 3 * 3");
assertEquals(0, state.getLocalReactions().size());
res.getContents().add(state);
assertEquals(1, state.getLocalReactions().size());
assertEquals("" + res.getSyntaxDiagnostics(), 0, res.getSyntaxDiagnostics().size());
}
public void testInvalidExpressionParsing() {
State state = createState("This is not a valid expression");
res.getContents().add(state);
assertEquals(1, res.getSyntaxDiagnostics().size());
assertTrue(res.getErrors().get(0) instanceof XtextSyntaxDiagnostic);
}
@Test
public void testStatechartSerializing1() throws Exception {
res.setSerializerEnabled(true);
Statechart statechart = createStatechart("internal: event Event1");
res.getContents().add(statechart);
Scope internalScope = (InternalScope) statechart.getScopes().get(0);
Event event = internalScope.getEvents().get(0);
event.setName("Event2");
assertEquals("internal: event Event2\n", statechart.getSpecification());
assertEquals("" + res.getSyntaxDiagnostics(), 0, res.getSyntaxDiagnostics().size());
}
@Test
public void testTransitionSerializing() throws Exception {
res.setSerializerEnabled(true);
Transition transition = createTransition("after 10\n s [true] / 3 * 3");
res.getContents().add(transition);
ReactionTrigger trigger = (ReactionTrigger) transition.getTrigger();
TimeEventSpec timeTrigger = stextFac.createTimeEventSpec();
timeTrigger.setType(TimeEventType.EVERY);
timeTrigger.setUnit(TimeUnit.SECOND);
PrimitiveValueExpression exp = expFac.createPrimitiveValueExpression();
IntLiteral literal = expFac.createIntLiteral();
literal.setValue(42);
exp.setValue(literal);
timeTrigger.setValue(exp);
trigger.getTriggers().add(timeTrigger);
assertEquals("after 10\n s , every 42 s [true] / 3 * 3", transition.getSpecification());
assertEquals("" + res.getErrors(), 0, res.getErrors().size());
}
@Test
public void testStateSerializing() throws Exception {
res.setSerializerEnabled(true);
State state = createState("entry / 3 * 3");
res.getContents().add(state);
LocalReaction reaction = (LocalReaction) state.getLocalReactions().get(0);
ReactionTrigger trigger = (ReactionTrigger) reaction.getTrigger();
ExitEvent exitEvent = stextFac.createExitEvent();
trigger.getTriggers().add(exitEvent);
assertEquals("entry , exit / 3 * 3", state.getSpecification());
assertEquals("" + res.getErrors(), 0, res.getErrors().size());
}
@Test
public void testLinkingSuccess() throws Exception {
Statechart statechart = createStatechart("internal: event Event1");
res.getContents().add(statechart);
Transition transition = createTransition("Event1 [true] / 3 * 3");
res.getContents().add(transition);
res.resolveLazyCrossReferences(CancelIndicator.NullImpl);
assertEquals("" + res.getLinkingDiagnostics(), 0, res.getLinkingDiagnostics().size());
ReactionTrigger trigger = (ReactionTrigger) transition.getTrigger();
RegularEventSpec eventSpec = (RegularEventSpec) trigger.getTriggers().get(0);
ElementReferenceExpression expression = (ElementReferenceExpression) eventSpec.getEvent();
EventDefinition reference = (EventDefinition) expression.getReference();
assertNotNull(reference);
assertEquals("Event1", reference.getName());
}
@Test
public void testLinkingError1() throws Exception {
Statechart statechart = createStatechart("internal: event Event1");
res.getContents().add(statechart);
Transition transition = createTransition("Event2 [true] / 3 * 3");
res.getContents().add(transition);
res.resolveLazyCrossReferences(CancelIndicator.NullImpl);
System.out.println(res.getLinkingDiagnostics());
assertEquals(1, res.getLinkingDiagnostics().size());
}
@Test
public void testLinkingError2() throws Exception {
Statechart statechart = createStatechart("internal: event Event1");
res.getContents().add(statechart);
Transition transition = createTransition("Event1 [true] / 3 * 3");
res.getContents().add(transition);
statechart.setSpecification("internal: event Event2");
res.resolveLazyCrossReferences(CancelIndicator.NullImpl);
assertEquals(1, res.getLinkingDiagnostics().size());
}
@Test
public void testParsingOnLoad() throws Exception {
File tmpFile = File.createTempFile("SCTResource", "test.test");
tmpFile.deleteOnExit();
URI uri = URI.createFileURI(tmpFile.getPath().toString());
Resource resource = new XMIResourceImpl(uri);
Statechart statechart = createStatechart("internal: event Event1");
resource.getContents().add(statechart);
Transition transition = createTransition("Event1 [true] / 3 * 3");
resource.getContents().add(transition);
resource.save(Collections.EMPTY_MAP);
res.setURI(uri);
res.load(Collections.EMPTY_MAP);
statechart = (Statechart) res.getContents().get(0);
transition = (Transition) res.getContents().get(1);
assertEquals("" + res.getErrors(), 0, res.getErrors().size());
ReactionTrigger trigger = (ReactionTrigger) transition.getTrigger();
RegularEventSpec eventSpec = (RegularEventSpec) trigger.getTriggers().get(0);
ElementReferenceExpression expression = (ElementReferenceExpression) eventSpec.getEvent();
EventDefinition reference = (EventDefinition) expression.getReference();
assertNotNull(reference);
assertEquals("Event1", reference.getName());
}
@Test
public void testRemoveOrphanedSyntaxDiagnostics() throws Exception {
Statechart statechart = createStatechart("invalid expression");
res.getContents().add(statechart);
assertEquals(1, res.getSyntaxDiagnostics().size());
statechart.setSpecification("internal: event Event1");
assertEquals(0, res.getSyntaxDiagnostics().size());
}
@Test
public void testRemoveOrphanedLinkingDiagnostics() throws Exception {
Statechart statechart = createStatechart("internal: event Event1");
res.getContents().add(statechart);
Transition transition = createTransition("Event2 [true] / 3 * 3");
res.getContents().add(transition);
res.resolveLazyCrossReferences(CancelIndicator.NullImpl);
assertEquals(1, res.getLinkingDiagnostics().size());
transition.setSpecification("Event1 [true] / 3 * 3");
res.resolveLazyCrossReferences(CancelIndicator.NullImpl);
assertEquals(0, res.getLinkingDiagnostics().size());
}
protected Statechart createStatechart(String exp) {
Statechart statechart = SGraphFactory.eINSTANCE.createStatechart();
statechart.setSpecification(exp);
return statechart;
}
protected Transition createTransition(String exp) {
Transition transition = SGraphFactory.eINSTANCE.createTransition();
transition.setSpecification(exp);
return transition;
}
protected State createState(String exp) {
State state = SGraphFactory.eINSTANCE.createState();
state.setSpecification(exp);
return state;
}
}