/**
* Copyright (c) 2010 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.sexec.interpreter.test;
import static org.junit.Assert.assertEquals;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.junit4.XtextRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.yakindu.base.expressions.expressions.Expression;
import org.yakindu.base.types.typesystem.GenericTypeSystem;
import org.yakindu.base.types.typesystem.ITypeSystem;
import org.yakindu.sct.model.stext.test.util.AbstractSTextTest;
import org.yakindu.sct.simulation.core.sexec.interpreter.IStatementInterpreter;
import org.yakindu.sct.simulation.core.sruntime.CompositeSlot;
import org.yakindu.sct.simulation.core.sruntime.ExecutionContext;
import org.yakindu.sct.simulation.core.sruntime.ExecutionEvent;
import org.yakindu.sct.simulation.core.sruntime.ExecutionVariable;
import org.yakindu.sct.simulation.core.sruntime.impl.CompositeSlotImpl;
import org.yakindu.sct.simulation.core.sruntime.impl.ExecutionEventImpl;
import org.yakindu.sct.simulation.core.sruntime.impl.ExecutionVariableImpl;
import com.google.inject.Inject;
/**
*
* @author andreas muelder - Initial contribution and API
*
*/
@RunWith(XtextRunner.class)
@InjectWith(SimulationInjectorProvider.class)
public class STextInterpreterTest extends AbstractSTextTest {
@Inject
private ExecutionContext context;
@Inject
private IStatementInterpreter interpreter;
@Inject
private ITypeSystem typeSystem;
@Test
public void testIntVariableAssignment() {
executeWithDefaultScope("intVar = 42");
assertEquals(42L, getIntValue());
}
@Test
public void testHexVariableAssignment() {
executeWithDefaultScope("intVar = 0xFF");
assertEquals(0xFFL, getIntValue());
}
@Test
public void testBoolTrueVariableAssignment() {
executeWithDefaultScope("boolVar = true");
assertEquals(true, getBoolValue());
}
@Test
public void testBoolFalseVariableAssignment() {
executeWithDefaultScope("boolVar = false");
assertEquals(false, getContext().getVariable("boolVar").getValue());
}
@Test
public void testRealVariableAssignment() {
executeWithDefaultScope("realVar = 42.0");
assertEquals(42.0d, getContext().getVariable("realVar").getValue());
}
@Test
public void testStringVariableAssignment() {
executeWithDefaultScope("stringVar = 'fortytwo'");
assertEquals("fortytwo", getStringValue());
}
@Test
public void testStringNullAssignment() {
executeWithDefaultScope("stringVar = null");
assertEquals(null, getStringValue());
}
@Test
public void testConditionalTrue() {
executeWithDefaultScope("intVar = true ? 42 : 1");
assertEquals(42L, getIntValue());
}
@Test
public void testConditionalFalse() {
executeWithDefaultScope("intVar = false ? 42 : 1");
assertEquals(1L, getIntValue());
}
@Test
public void testNestedExpression() {
executeWithDefaultScope("intVar = (1 + 1) * 2");
assertEquals(4L, getIntValue());
}
@Test
public void testBooleanOr() {
executeWithDefaultScope("boolVar = true || false");
assertEquals(true, getBoolValue());
}
@Test
public void testBooleanAnd() {
executeWithDefaultScope("boolVar = true && false");
assertEquals(false, getContext().getVariable("boolVar").getValue());
}
@Test
public void testBitwiseXor() {
executeWithDefaultScope("intVar = 0xF0F0 ^ 0xFF00");
assertEquals(0x0FF0L, getContext().getVariable("intVar").getValue());
}
@Test
public void testBitwiseOr() {
executeWithDefaultScope("intVar = 0xF0F0 | 0xFFFF");
assertEquals(0xFFFFL, getContext().getVariable("intVar").getValue());
}
@Test
public void testBitwiseAnd() {
executeWithDefaultScope("intVar = 0xF0F0 & 0xFFFF");
assertEquals(0x0F0F0L, getContext().getVariable("intVar").getValue());
}
@Test
public void testBoolEqual() {
executeWithDefaultScope("boolVar = false == false");
assertEquals(true, getBoolValue());
}
@Test
public void testIntEqual() {
executeWithDefaultScope("boolVar = 1 == 1");
assertEquals(true, getBoolValue());
}
@Test
public void testRealEqual() {
executeWithDefaultScope("boolVar = 1.0f == 1.0f");
assertEquals(true, getBoolValue());
}
@Test
public void testStringEqual() {
executeWithDefaultScope("boolVar = 'string' == 'string'");
assertEquals(true, getBoolValue());
}
@Test
public void testBoolNotEqual() {
executeWithDefaultScope("boolVar = true != false");
assertEquals(true, getBoolValue());
}
@Test
public void testIntNotEqual() {
executeWithDefaultScope("boolVar = 1 != 2");
assertEquals(true, getBoolValue());
}
@Test
public void testRealNotEqual() {
executeWithDefaultScope("boolVar = 1.0f != 2.0f");
assertEquals(true, getBoolValue());
}
@Test
public void testStringNotEqual() {
executeWithDefaultScope("boolVar = 'string' != 'string2'");
assertEquals(true, getBoolValue());
}
@Test
public void testIntGreaterEqual() {
executeWithDefaultScope("boolVar = 2 >= 1");
assertEquals(true, getBoolValue());
}
@Test
public void testRealGreaterEqual() {
executeWithDefaultScope("boolVar = 2.0f >= 2.0f");
assertEquals(true, getBoolValue());
}
@Test
public void testIntSmallerEqual() {
executeWithDefaultScope("boolVar = 1 <= 2");
assertEquals(true, getBoolValue());
}
@Test
public void testRealSmallerEqual() {
executeWithDefaultScope("boolVar = 2.0f <= 2.0f");
assertEquals(true, getBoolValue());
}
@Test
public void testIntGreater() {
executeWithDefaultScope("boolVar = 2 > 1");
assertEquals(true, getBoolValue());
}
@Test
public void testRealGreater() {
executeWithDefaultScope("boolVar = 2.1f > 2.0f");
assertEquals(true, getBoolValue());
}
@Test
public void testIntSmaller() {
executeWithDefaultScope("boolVar = 1 < 2");
assertEquals(true, getBoolValue());
}
@Test
public void testRealSmaller() {
executeWithDefaultScope("boolVar = 2.0f < 2.1f");
assertEquals(true, getBoolValue());
}
@Test
public void testIntPositive() {
executeWithDefaultScope("intVar = + 1");
assertEquals(1L, getIntValue());
executeWithDefaultScope("intVar = +2");
assertEquals(2L, getIntValue());
}
@Test
public void testRealPositive() {
executeWithDefaultScope("realVar = +1.0");
assertEquals(1.0d, getRealValue());
}
@Test
public void testIntNegative() {
executeWithDefaultScope("intVar = - 1");
assertEquals(-1L, getIntValue());
executeWithDefaultScope("intVar = -2");
assertEquals(-2L, getIntValue());
}
@Test
public void testRealNegative() {
executeWithDefaultScope("realVar = -1.0f");
assertEquals(-1.0d, getRealValue());
}
@Test
public void testIntPlus() {
executeWithDefaultScope("intVar = 42 + 1");
assertEquals(43L, getIntValue());
}
@Test
public void testRealPlus() {
executeWithDefaultScope("realVar = 42.0 + 1.0");
assertEquals(43.0d, getRealValue());
}
@Test
public void testIntMinus() {
executeWithDefaultScope("intVar = 42 - 1");
assertEquals(41L, getIntValue());
}
@Test
public void testRealMinus() {
executeWithDefaultScope("realVar = 42.0f - 1.0f");
assertEquals(41.0d, getRealValue());
}
@Test
public void testIntMultiply() {
executeWithDefaultScope("intVar = 42 * 2");
assertEquals(84L, getIntValue());
}
@Test
public void testRealMultiply() {
executeWithDefaultScope("realVar = 42.0f * 2.0f");
assertEquals(84.0d, getRealValue());
}
@Test
public void testIntDivide() {
executeWithDefaultScope("intVar = 42 / 2");
assertEquals(21L, getIntValue());
}
@Test
public void testRealDivide() {
executeWithDefaultScope("realVar = 42.0f / 2.0f");
assertEquals(21.0d, getRealValue());
}
@Test
public void testIntModulo() {
executeWithDefaultScope("intVar = 42 % 2");
assertEquals(0L, getIntValue());
}
@Test
public void testRealModulo() {
executeWithDefaultScope("realVar = 42.0f % 2.0f");
assertEquals(0.0d, getRealValue());
}
@Test
public void testIntLeft() {
executeWithDefaultScope("intVar = 42 << 2");
assertEquals(168L, getIntValue());
}
@Test
public void testIntRight() {
executeWithDefaultScope("intVar = 42 >> 2");
assertEquals(10L, getIntValue());
}
@Test
public void testIntAnd() {
executeWithDefaultScope("intVar= 9 & 12");
assertEquals(8L, getIntValue());
}
@Test
public void testIntXor() {
executeWithDefaultScope("intVar= 9 ^ 12");
assertEquals(5L, getIntValue());
}
@Test
public void testIntOr() {
executeWithDefaultScope("intVar= 9 | 12");
assertEquals(13L, getIntValue());
}
@Test
public void testIntBitComplement() {
executeWithDefaultScope("intVar= ~9");
assertEquals(-10L, getIntValue());
}
@Test
public void testNot() {
executeWithDefaultScope("boolVar = ! true");
assertEquals(false, getBoolValue());
}
@Test
public void testPrirority() {
executeWithDefaultScope("intVar = 1 + 2 * 3");
assertEquals(7L, getIntValue());
}
@Test
public void testNested() {
executeWithDefaultScope("intVar = (1 + 2) * 3");
assertEquals(9L, getIntValue());
}
@Test
public void testIntPlusAssign() {
executeWithDefaultScope("intVar=42");
executeWithDefaultScope("intVar+=42");
assertEquals(84L, getIntValue());
}
@Test
public void testRealPlusAssign() {
executeWithDefaultScope("realVar = 42.0");
executeWithDefaultScope("realVar+=42.0");
assertEquals(84.0d, getRealValue());
}
@Test
public void testIntMinusAssign() {
executeWithDefaultScope("intVar=42");
executeWithDefaultScope("intVar-=10");
assertEquals(32L, getIntValue());
}
@Test
public void testRealMinusAssign() {
executeWithDefaultScope("realVar=42.0f");
executeWithDefaultScope("realVar-=10.0");
assertEquals(32.0d, getRealValue());
}
@Test
public void testIntMultAssign() {
executeWithDefaultScope("intVar=42");
executeWithDefaultScope("intVar*=1");
assertEquals(42L, getIntValue());
}
@Test
public void testRealMultAssign() {
executeWithDefaultScope("realVar=42.0f");
executeWithDefaultScope("realVar*=1.0");
assertEquals(42.0d, getRealValue());
}
@Test
public void testIntDivAssign() {
executeWithDefaultScope("intVar=42");
executeWithDefaultScope("intVar/=1");
assertEquals(42L, getIntValue());
}
@Test
public void testRealDivAssign() {
executeWithDefaultScope("realVar=42.0f");
executeWithDefaultScope("realVar/=1.0f");
assertEquals(42.0d, getRealValue());
}
@Test
public void testIntModAssign() {
executeWithDefaultScope("intVar=42");
executeWithDefaultScope("intVar%=1");
assertEquals(0L, getIntValue());
}
@Test
public void testRealModAssign() {
executeWithDefaultScope("realVar=42.0f");
executeWithDefaultScope("realVar%=1.0f");
assertEquals(0.0d, getRealValue());
}
@Test
public void testPlainTrue() {
assertEquals(true, executeExpression("true"));
}
@Test
public void testPlainFalse() {
assertEquals(false, executeExpression("false"));
}
@Test
public void testEnumEqualsExpression() {
String scope = "internal: var enumVar : EnumType";
execute(scope, "enumVar = EnumType.B");
assertEquals(false, execute(scope, "enumVar == EnumType.A"));
assertEquals(true, execute(scope, "enumVar == EnumType.B"));
}
@Test
public void testEnumAssignment() {
execute("internal: var enumVar : EnumType", "enumVar = EnumType.B");
assertEquals(1L, getEnumValue());
}
@Test
public void testComplexTypeEqualsExpression() {
assertEquals(true, execute("internal: var cpVar : ComplexType", "cpVar.x == 0"));
}
@Test
public void testComplexTypeAssignment() {
execute("internal: var cpVar : ComplexType", "cpVar.x = 42");
assertEquals(42L, context.getVariable("cpVar.x").getValue());
}
@Test
public void testEqualsExpressionForComplexTypeAlias() {
assertEquals(true, execute("internal: alias MyComplexType : ComplexType var cpVar : MyComplexType", "cpVar.x == 0"));
}
@Test
public void testAssignmentToComplexTypeAlias() {
execute("internal: alias MyComplexType : ComplexType var cpVar : MyComplexType", "cpVar.x = 42");
assertEquals(42L, context.getVariable("cpVar.x").getValue());
}
// Convenience...
@Before
public void setup() {
initContext();
}
private void initContext() {
// "event abc operation foo() var intVar : integer var boolVar : boolean
// var realVar : real
ExecutionVariable intVar = new ExecutionVariableImpl();
intVar.setName("intVar");
intVar.setFqName("intVar");
intVar.setType(typeSystem.getType(GenericTypeSystem.INTEGER));
intVar.setValue(0);
context.getSlots().add(intVar);
ExecutionVariable boolVar = new ExecutionVariableImpl();
boolVar.setName("boolVar");
boolVar.setFqName("boolVar");
boolVar.setType(typeSystem.getType(GenericTypeSystem.BOOLEAN));
boolVar.setValue(false);
context.getSlots().add(boolVar);
ExecutionVariable realVar = new ExecutionVariableImpl();
realVar.setName("realVar");
realVar.setFqName("realVar");
realVar.setType(typeSystem.getType(GenericTypeSystem.REAL));
realVar.setValue(0.0f);
context.getSlots().add(realVar);
ExecutionVariable stringVar = new ExecutionVariableImpl();
stringVar.setName("stringVar");
stringVar.setFqName("stringVar");
stringVar.setType(typeSystem.getType(GenericTypeSystem.STRING));
stringVar.setValue("");
context.getSlots().add(stringVar);
ExecutionEvent event = new ExecutionEventImpl();
event.setName("abc");
event.setFqName("abc");
event.setType(typeSystem.getType(GenericTypeSystem.INTEGER));
context.getSlots().add(event);
ExecutionVariable enumVar = new ExecutionVariableImpl();
enumVar.setName("enumVar");
enumVar.setFqName("enumVar");
enumVar.setType(typeSystem.getType(GenericTypeSystem.INTEGER));
context.getSlots().add(enumVar);
CompositeSlot cpVar = new CompositeSlotImpl();
cpVar.setName("cpVar");
cpVar.setFqName("cpVar");
ExecutionVariable featureVar = new ExecutionVariableImpl();
featureVar.setName("x");
featureVar.setFqName("cpVar.x");
featureVar.setType(typeSystem.getType(GenericTypeSystem.INTEGER));
featureVar.setValue(0);
cpVar.getSlots().add(featureVar);
context.getSlots().add(cpVar);
}
protected Object getBoolValue() {
return context.getVariable("boolVar").getValue();
}
protected Object getIntValue() {
return context.getVariable("intVar").getValue();
}
protected Object getRealValue() {
return context.getVariable("realVar").getValue();
}
protected Object getStringValue() {
return context.getVariable("stringVar").getValue();
}
protected Object getEnumValue() {
return context.getVariable("enumVar").getValue();
}
protected Object executeWithDefaultScope(String expression) {
Expression statement = (Expression) parseExpression(expression, Expression.class.getSimpleName(), internalScope());
return interpreter.evaluateStatement(statement, context);
}
protected Object execute(String scope, String expression) {
Expression statement = (Expression) parseExpression(expression, Expression.class.getSimpleName(), scope);
return interpreter.evaluateStatement(statement, context);
}
protected Object executeExpression(String scope, String expression) {
Expression statement = (Expression) parseExpression(expression, Expression.class.getSimpleName(), scope);
return interpreter.evaluateStatement(statement, context);
}
protected Object executeExpression(String expression) {
Expression statement = (Expression) parseExpression(expression, Expression.class.getSimpleName());
return interpreter.evaluateStatement(statement, context);
}
public ExecutionContext getContext() {
return context;
}
@After
public void tearDown() {
context = null;
}
}