package com.sap.finex.interpreter.tests; import java.lang.reflect.InvocationTargetException; import junit.framework.TestCase; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.IProgressService; import structure.Field; import structure.FinexClass; import structure.Type; import behavior.expressions.BinaryBooleanOperator; import behavior.expressions.BinaryNumericOperator; import behavior.expressions.Not; import behavior.expressions.literals.BooleanLiteral; import behavior.expressions.literals.DecimalLiteral; import behavior.expressions.literals.IntegerLiteral; import com.sap.finex.interpreter.Activator; import com.sap.finex.interpreter.FinexInMemoryRepository; import com.sap.finex.interpreter.FinexInterpreter; import com.sap.finex.interpreter.FinexStackFrame; import com.sap.finex.interpreter.objects.FinexNativeObject; import com.sap.finex.metamodel.utils.MetamodelUtils; import com.sap.mi.fwk.ConnectionManager; import com.sap.runlet.abstractinterpreter.objects.RunletObject; import com.sap.runlet.abstractinterpreter.util.Fraction; import com.sap.tc.moin.repository.Connection; public class TestsWithProgrammaticModelConstruction extends TestCase { private FinexInterpreter interpreter; @Override public void setUp() { Connection conn = getConnection("finex.stdlib"); interpreter = new FinexInterpreter(conn, new FinexInMemoryRepository(Activator.getDefault().getModelAdapter())); interpreter.push(new FinexStackFrame()); } public void testBinaryIntegerOperationsSingle() throws SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { BinaryNumericOperator bno = interpreter.getConnection().createElement(BinaryNumericOperator.CLASS_DESCRIPTOR); bno.setType(MetamodelUtils.findClass(interpreter.getConnection(), "Integer")); bno.setOperator("*"); IntegerLiteral left = createIntLiteral(28); bno.setLeft(left); IntegerLiteral right = createIntLiteral(4); bno.setRight(right); RunletObject<Field, Type, FinexClass> result = interpreter.evaluate(bno); assertTrue(result instanceof FinexNativeObject); assertEquals(28l*4l, ((FinexNativeObject) result).getNativeObject()); bno.setOperator("/"); result = interpreter.evaluate(bno); assertTrue(result instanceof FinexNativeObject); assertEquals(28l/4l, ((FinexNativeObject) result).getNativeObject()); bno.setOperator("-"); result = interpreter.evaluate(bno); assertTrue(result instanceof FinexNativeObject); assertEquals(28l-4l, ((FinexNativeObject) result).getNativeObject()); bno.setOperator("+"); result = interpreter.evaluate(bno); assertTrue(result instanceof FinexNativeObject); assertEquals(28l+4l, ((FinexNativeObject) result).getNativeObject()); } public void testBinaryDecimalOperationsSingle() throws SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { BinaryNumericOperator bno = interpreter.getConnection().createElement(BinaryNumericOperator.CLASS_DESCRIPTOR); bno.setType(MetamodelUtils.findClass(interpreter.getConnection(), "Decimal")); bno.setOperator("*"); DecimalLiteral left = createDecLiteral("28"); bno.setLeft(left); DecimalLiteral right = createDecLiteral("5"); bno.setRight(right); RunletObject<Field, Type, FinexClass> result = interpreter.evaluate(bno); assertTrue(result instanceof FinexNativeObject); assertEquals(new Fraction(28).times(new Fraction(5)), ((FinexNativeObject) result).getNativeObject()); bno.setOperator("/"); result = interpreter.evaluate(bno); assertTrue(result instanceof FinexNativeObject); assertEquals(new Fraction(28).dividedBy(new Fraction(5)), ((FinexNativeObject) result).getNativeObject()); bno.setOperator("-"); result = interpreter.evaluate(bno); assertTrue(result instanceof FinexNativeObject); assertEquals(new Fraction(28).minus(new Fraction(5)), ((FinexNativeObject) result).getNativeObject()); bno.setOperator("+"); result = interpreter.evaluate(bno); assertTrue(result instanceof FinexNativeObject); assertEquals(new Fraction(28).plus(new Fraction(5)), ((FinexNativeObject) result).getNativeObject()); } private IntegerLiteral createIntLiteral(long value) { IntegerLiteral literal = interpreter.getConnection().createElement(IntegerLiteral.CLASS_DESCRIPTOR); literal.setLiteral(Long.toString(value)); return literal; } private DecimalLiteral createDecLiteral(String value) { DecimalLiteral literal = interpreter.getConnection().createElement(DecimalLiteral.CLASS_DESCRIPTOR); literal.setLiteral(value); return literal; } public void testSimpleNot() throws SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { BooleanLiteral op = createBoolLiteral(true); Not not = interpreter.getConnection().createElement(Not.CLASS_DESCRIPTOR); not.setOperand(op); RunletObject<Field, Type, FinexClass> result = interpreter.evaluate(not); assertTrue(result instanceof FinexNativeObject); assertEquals(false, ((FinexNativeObject) result).getNativeObject()); op = createBoolLiteral(false); not.setOperand(op); result = interpreter.evaluate(not); assertTrue(result instanceof FinexNativeObject); assertEquals(true, ((FinexNativeObject) result).getNativeObject()); } public void testBooleanAndAndOrSingle() throws SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { BinaryBooleanOperator bbo = interpreter.getConnection().createElement(BinaryBooleanOperator.CLASS_DESCRIPTOR); bbo.setOperator("and"); BooleanLiteral left = createBoolLiteral(true); bbo.setLeft(left); BooleanLiteral right = createBoolLiteral(false); bbo.setRight(right); RunletObject<Field, Type, FinexClass> result = interpreter.evaluate(bbo); assertTrue(result instanceof FinexNativeObject); assertEquals(false, ((FinexNativeObject) result).getNativeObject()); bbo.setOperator("or"); left = createBoolLiteral(true); bbo.setLeft(left); right = createBoolLiteral(false); bbo.setRight(right); result = interpreter.evaluate(bbo); assertTrue(result instanceof FinexNativeObject); assertEquals(true, ((FinexNativeObject) result).getNativeObject()); bbo.setOperator("and"); left = createBoolLiteral(true); bbo.setRight(left); right = createBoolLiteral(true); bbo.setLeft(right); result = interpreter.evaluate(bbo); assertTrue(result instanceof FinexNativeObject); assertEquals(true, ((FinexNativeObject) result).getNativeObject()); bbo.setOperator("or"); left = createBoolLiteral(false); bbo.setLeft(left); right = createBoolLiteral(false); bbo.setRight(right); result = interpreter.evaluate(bbo); assertTrue(result instanceof FinexNativeObject); assertEquals(false, ((FinexNativeObject) result).getNativeObject()); } private BooleanLiteral createBoolLiteral(boolean value) { BooleanLiteral literal = interpreter.getConnection().createElement(BooleanLiteral.CLASS_DESCRIPTOR); literal.setLiteral(Boolean.toString(value)); return literal; } public void testIntegerLiteral() throws SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { IntegerLiteral il = createIntLiteral(123); RunletObject<Field, Type, FinexClass> result = interpreter.evaluate(il); assertTrue(result instanceof FinexNativeObject); assertEquals(123l, ((FinexNativeObject) result).getNativeObject()); } public void testDecimalLiteral() throws SecurityException, IllegalArgumentException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { DecimalLiteral dl = interpreter.getConnection().createElement(DecimalLiteral.CLASS_DESCRIPTOR); dl.setLiteral("123.45"); RunletObject<Field, Type, FinexClass> result = interpreter.evaluate(dl); assertTrue(result instanceof FinexNativeObject); assertEquals(new Fraction(12345, 100), ((FinexNativeObject) result).getNativeObject()); } private static Connection getConnection(String projectName) { final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); final Connection[] conn = new Connection[1]; IRunnableWithProgress operation = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { // non UI thread try { project.open(/* progress monitor */null); } catch (CoreException e) { throw new RuntimeException(e); } conn[0] = ConnectionManager.getInstance().getOrCreateDefaultConnection(project); } }; IProgressService ps = PlatformUI.getWorkbench().getProgressService(); try { if (Thread.currentThread() == Display.getDefault().getThread()) { ps.busyCursorWhile(operation); } else { operation.run(null); } } catch (Exception e) { throw new RuntimeException(e); } return conn[0]; } }