/*******************************************************************************
* Copyright (c) 2005, 2009 committers of openArchitectureWare 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 openArchitectureWare - initial API and implementation
*******************************************************************************/
package org.eclipse.xtend;
import java.io.StringReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import junit.framework.TestCase;
import org.eclipse.internal.xtend.xtend.ast.Extension;
import org.eclipse.internal.xtend.xtend.ast.ExtensionFile;
import org.eclipse.internal.xtend.xtend.parser.ParseFacade;
import org.eclipse.xtend.expression.ExecutionContextImpl;
import org.eclipse.xtend.type.impl.java.JavaMetaModel;
import org.eclipse.xtend.type.impl.java.beans.JavaBeansStrategy;
import org.eclipse.xtend.typesystem.javabeansimpl.test.TypeA;
import org.eclipse.xtend.typesystem.javabeansimpl.test.TypeB;
public class ExtensionEvaluationTest extends TestCase {
private ExecutionContextImpl ec;
@Override
protected void setUp() throws Exception {
ec = new ExecutionContextImpl();
ec.registerMetaModel(new JavaMetaModel("asdf", new JavaBeansStrategy()));
}
private ExtensionFile parse(final String expression) {
return ParseFacade.file(new StringReader(expression), "nofile");
}
public void testVoidInSignature() throws Exception {
final ExtensionFile file = parse(
"foo(String str) : 'String';" +
"foo(Integer int) : 'Int';" +
"foo(Void void) : 'void';");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
XtendFacade facade = XtendFacade.create(ec);
assertEquals("String",facade.call("foo", "String"));
assertEquals("Int",facade.call("foo", new Long(42)));
assertEquals("void",facade.call("foo", (Object) null));
}
public final void testWithEverything() {
final ExtensionFile file = parse("String toUpperCase(String str) : JAVA org.eclipse.xtend.Helper.toUpperCase(java.lang.String) ; \n"
+ "\n"
+ "String privateHelper(String str) : JAVA org.eclipse.xtend.Helper.privateHelper(java.lang.String) ; \n"
+ "\n"
+ "String nonStaticHelper(String str) : JAVA org.eclipse.xtend.Helper.nonStaticHelper(java.lang.String) ; \n"
+ "\n" + "/* \n" + " * Meine Funktion \n" + " */ \n" + "myExtension(Object val) : {val} ; \n");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
final Object[] params = new Object[] { "test" };
Extension ext = ec.getExtension("toUpperCase", params);
assertEquals("TEST", ext.evaluate(params, ec));
ext = ec.getExtension("myExtension", params);
assertEquals(Collections.singletonList("test"), ext.evaluate(params, ec));
}
public final void testJavaExtension2() {
final ExtensionFile file = parse("Collection union(Collection c1,Collection c2) : JAVA "
+ "org.eclipse.xtend.Helper.union(java.util.Collection,java.util.Collection) ; \n");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
final Object[] params = new Object[] { Collections.singleton("1"), Collections.singleton("2") };
final Extension ext = ec.getExtension("union", params);
final Collection<?> result = (Collection<?>) ext.evaluate(params, ec);
assertTrue(result.size() == 2);
assertTrue(result.contains("1"));
assertTrue(result.contains("2"));
}
public final void testPolymorphism() {
final ExtensionFile file = parse("ext(Object val) : 'Object' ; \n" + "ext(List[Object] val) : 'List' ; \n"
+ "ext(Collection[Object] val) : 'Collection' ; \n" + "ext(Integer val) : 'Integer' ; \n");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
Extension ext = ec.getExtension("ext", new Object[] { "test" });
assertEquals("Object", ext.evaluate(new Object[] { "test" }, ec));
ext = ec.getExtension("ext", new Object[] { Collections.EMPTY_SET });
assertEquals("Collection", ext.evaluate(new Object[] { Collections.EMPTY_SET }, ec));
ext = ec.getExtension("ext", new Object[] { Collections.EMPTY_LIST });
assertEquals("List", ext.evaluate(new Object[] { Collections.EMPTY_LIST }, ec));
ext = ec.getExtension("ext", new Object[] { new Integer(2) });
assertEquals("Integer", ext.evaluate(new Object[] { new Integer(2) }, ec));
}
public final void testRecursion() {
final ExtensionFile file = parse("List[Integer] recExtension(Integer von,Integer bis) : von>=bis ? {von} : recExtension(von,bis-1).add(bis) ; \n");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
final Extension ext = ec.getExtension("recExtension", new Object[] { new BigInteger("5"), new BigInteger("10") });
final List<BigInteger> expected = new ArrayList<BigInteger>();
for (int i = 5; i <= 10; i++) {
expected.add(new BigInteger(""+i));
}
final Object evalResult = ext.evaluate(new Object[] { new BigInteger("5"), new BigInteger("10") }, ec);
assertEquals(expected, evalResult);
}
public final void testMemberPosition() {
final ExtensionFile file = parse("ext1(String txt) : 'test'+txt ;" + "ext2(String txt) : txt.ext1() ;");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
final Extension ext = ec.getExtension("ext2", new Object[] { "fall" });
final Object evalResult = ext.evaluate(new Object[] { "fall" }, ec);
assertEquals("testfall", evalResult);
}
public final void testCachedExtension() {
final ExtensionFile file = parse("cached String ext(String txt) : JAVA org.eclipse.xtend.ExtensionEvaluationTest.testMethod(java.lang.String);");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
final Extension ext = ec.getExtension("ext", new Object[] { "test" });
String expected = "test" + String.valueOf(magic);
assertEquals(expected, ext.evaluate(new Object[] { "test" }, ec));
assertEquals(expected, ext.evaluate(new Object[] { "test" }, ec));
assertEquals(expected, ext.evaluate(new Object[] { "test" }, ec));
assertEquals(expected, ext.evaluate(new Object[] { "test" }, ec));
}
private static int magic = 0;
public final static String testMethod(final String s) {
return s + magic++;
}
public final void testCreateExtension() {
final ExtensionFile file = parse("create List l test(String s) : l.add(s) ;");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
final List<?> l = (List<?>) (file.getExtensions().get(0)).evaluate(new String[] { "test" }, ec);
assertEquals(Collections.singletonList("test"), l);
}
public final void testCreateExtension1() {
final ExtensionFile file = parse("create List test(String s) : add(s) ;");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
final List<?> l = (List<?>) (file.getExtensions().get(0)).evaluate(new String[] { "test" }, ec);
assertEquals(Collections.singletonList("test"), l);
}
public final void testAmbigous() {
final ExtensionFile file = parse("import " + TypeA.class.getPackage().getName().replaceAll("\\.", "::") + ";"
+ "doStuff(TypeA this) : true; " + "doStuff(TypeC this) : false;");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
assertNotNull(ec.getExtension("doStuff", new Object[] { new TypeA() }));
try {
ec.getExtension("doStuff", new Object[] { new TypeB() });
fail("Ambigous operation exception expected");
}
catch (final RuntimeException re) {
// expected
System.out.println(re.getMessage());
}
}
public final void testBug134626() {
final ExtensionFile file = parse("String someExt(TestA someA) : JAVA " + getClass().getName()
+ "(java.lang.String) ; \n");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
}
public static String methodForBug134626() {
return "Hello";
}
public void testAdvices() throws Exception {
final ExtensionFile file = parse("doStuff() : '_THE_'; " + "doStuff(String s) : s;");
ec = (ExecutionContextImpl) ec.cloneWithResource(file);
ec.registerExtensionAdvices("org::eclipse::xtend::Advices");
assertEquals("AROUND_THE_END", call(ec, "doStuff"));
assertEquals("AROUNDAROUND_HONK_ENDEND", call(ec, "doStuff", "_HONK_"));
}
private Object call(ExecutionContextImpl ctx, String string, Object... params) {
Extension ext = ctx.getExtension(string, params);
return ext.evaluate(params, ctx);
}
}