package se.krka.kahlua.annotation;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.fail;
import java.io.File;
import se.krka.kahlua.integration.doc.ApiDocumentationExporter;
import java.io.StringWriter;
import se.krka.kahlua.integration.doc.DokuWikiPrinter;
import se.krka.kahlua.integration.expose.LuaJavaClassExposer;
import se.krka.kahlua.converter.LuaConverterManager;
import se.krka.kahlua.converter.LuaNumberConverter;
import se.krka.kahlua.converter.LuaTableConverter;
import se.krka.kahlua.converter.LuaConversionError;
import se.krka.kahlua.integration.processor.LuaClassDebugInformation;
import se.krka.kahlua.integration.processor.LuaMethodDebugInformation;
import org.junit.Test;
import java.io.IOException;
import java.util.Map;
import org.junit.Before;
import se.krka.kahlua.luaj.compiler.LuaCompiler;
import se.krka.kahlua.vm.LuaClosure;
import se.krka.kahlua.vm.LuaState;
import se.krka.kahlua.vm.LuaTable;
public class AnnotationTest {
private LuaConverterManager manager;
private LuaState state;
private LuaJavaClassExposer factory;
@Before
public void setup() {
manager = new LuaConverterManager();
LuaNumberConverter.install(manager);
LuaTableConverter.install(manager);
state = new LuaState(System.out);
factory = new LuaJavaClassExposer(state, manager);
}
@Test
public void testInheritedAnnotation() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
{
InheritedAnnotationClass testObject = new InheritedAnnotationClass();
state.getEnvironment().rawset("testObject", testObject);
String testString = "testObject:inheritedMethodWithArgs('hello', 123)";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
assertEquals(testObject.imba, 123);
assertEquals(testObject.zomg, "hello");
}
{
InheritedAnnotationClass testObject = new InheritedAnnotationClass();
state.getEnvironment().rawset("testObject", testObject);
String testString = "assert(testObject.baseMethodWithArgs); testObject:baseMethodWithArgs(112233, 'world')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
assertEquals(testObject.foo, 112233);
assertEquals(testObject.bar, "world");
}
}
@Test
public void testOverride() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
{
InheritedAnnotationClass testObject = new InheritedAnnotationClass();
state.getEnvironment().rawset("testObject", testObject);
String testString = "assert(testObject:baseMethod2() == 'Inherited')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
}
{
BaseAnnotationClass testObject = new BaseAnnotationClass();
state.getEnvironment().rawset("testObject", testObject);
String testString = "assert(testObject:baseMethod2() == 'Base')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
}
}
@Test
public void testBadCall() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
InheritedAnnotationClass testObject = new InheritedAnnotationClass();
state.getEnvironment().rawset("testObject", testObject);
String testString = "testObject:inheritedMethodWithArgs('hello', 'world')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
try {
state.call(closure, null);
fail();
} catch (Exception e) {
assertNotNull(e.getMessage());
assertEquals("No conversion found from class java.lang.String to class java.lang.Integer at argument #2, imba", e.getMessage());
}
}
@Test
public void testNotEnoughParameters() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
InheritedAnnotationClass testObject = new InheritedAnnotationClass();
state.getEnvironment().rawset("testObject", testObject);
String testString = "testObject:inheritedMethodWithArgs('hello')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
try {
state.call(closure, null);
fail();
} catch (Exception e) {
assertEquals(e.getMessage(), "Expected 2 arguments but got 1. Correct syntax: obj:inheritedMethodWithArgs(zomg, imba)");
}
}
@Test
public void testGlobalFunctionWrongNumberOfParams() throws IOException {
InheritedAnnotationClass testObject = new InheritedAnnotationClass();
factory.exposeGlobalFunctions(testObject);
String testString = "myGlobalFunction('hello')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
try {
state.call(closure, null);
fail();
} catch (Exception e) {
assertEquals(e.getMessage(), "Expected 4 arguments but got 1. Correct syntax: myGlobalFunction(s, d, b, i)");
}
}
@Test
public void testGlobalFunctionOk() throws IOException {
InheritedAnnotationClass testObject = new InheritedAnnotationClass();
factory.exposeGlobalFunctions(testObject);
String testString = "myGlobalFunction('hello', 1, true, 3)";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
assertEquals(testObject.s, "hello");
assertEquals(testObject.d, 1.0);
assertEquals(testObject.b, true);
assertEquals(testObject.i, 3);
}
@Test
public void testGlobalFunctionReturnValues() throws IOException {
InheritedAnnotationClass testObject = new InheritedAnnotationClass();
factory.exposeGlobalFunctions(testObject);
String testString = "local a, b = myGlobalFunction2(5, 7); assert(a == 5*7, '1st'); assert(b == 5+7, '2nd');";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
assertEquals(testObject.x, 5);
assertEquals(testObject.y, 7);
}
@Test
public void testMethodWithMultipleReturnValues() throws IOException {
InheritedAnnotationClass testObject = new InheritedAnnotationClass();
factory.exposeClass(InheritedAnnotationClass.class);
state.getEnvironment().rawset("testObject", testObject);
String testString = "local a, b = testObject:inheritedMethodWithMultipleReturns(); assert(a == 'Hello', '1st'); assert(b == 'World', '2nd');";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
testString = "local a, b = testObject:inheritedMethodWithMultipleReturns2('prefix'); assert(a == 'prefixHello', '1st'); assert(b == 'prefixWorld', '2nd');";
closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
}
@Test
public void testUserdataProperties() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
state.getEnvironment().rawset("testObject1", new InheritedAnnotationClass());
state.getEnvironment().rawset("testObject2", new InheritedAnnotationClass());
String testString =
"withproperties(testObject1);" +
"withproperties(testObject2);" +
"testObject1.key1 = 'A';" +
"testObject1.key2 = 'B';" +
"testObject1.key3 = 'C';" +
"testObject2.key1 = '1';" +
"testObject2.key2 = '2';" +
"testObject2.key3 = '3';" +
"assert(testObject1.key == nil, 'test1');" +
"assert(testObject1.key1 == 'A', 'test2');" +
"assert(testObject1.key2 == 'B', 'test3');" +
"assert(testObject1.key3 == 'C', 'test4');" +
"assert(testObject2.key1 == '1', 'test5');" +
"assert(testObject2.key2 == '2', 'test6');" +
"assert(testObject2.key3 == '3', 'test7');" +
"";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
}
@Test
public void testDebugData() throws SecurityException, IOException, ClassNotFoundException {
LuaClassDebugInformation classDebugInfo = LuaClassDebugInformation.getFromStream(InheritedAnnotationClass.class);
assertNotNull(classDebugInfo);
assertNotNull(classDebugInfo.methods);
assertFalse(classDebugInfo.methods.isEmpty());
}
@Test
public void testGetDebugData() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
factory.exposeClass(LuaMethodDebugInformation.class);
factory.exposeGlobalFunctions(factory);
state.getEnvironment().rawset("testObject1", new InheritedAnnotationClass());
String testString = "assert(testObject1, '0')" +
"assert(testObject1.inheritedMethodWithMultipleReturns2, '1');" +
"d = getDebugInfo(testObject1.inheritedMethodWithMultipleReturns2)" +
"assert(d ~= nil, '2')" +
"local name, type, desc = d:getParameter(1)" +
"assert(name == 'a')" +
"assert(type == 'String')" +
"assert(desc == nil)" +
"assert(nil == d:getParameter(2))" +
"";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
testString = "assert(testObject1, '0')" +
"assert(testObject1.inheritedMethodWithArgs, '1');" +
"d = getDebugInfo(testObject1.inheritedMethodWithArgs)" +
"assert(d ~= nil, '2')" +
"local name, type, desc = d:getParameter(1)" +
"assert(name == 'zomg', name)" +
"assert(type == 'String', type)" +
"assert(desc == nil, desc)" +
"local name, type, desc = d:getParameter(2)" +
"assert(name == 'imba', name)" +
"assert(type == 'int', type)" +
"assert(desc == nil, desc)" +
"assert(nil == d:getParameter(3))" +
"";
closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
}
@Test
public void testStaticMethod() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
String testString = "s = staticMethod(); assert(s == 'Hello world');";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
}
@Test
public void testGetExposedClasses() throws LuaConversionError {
factory.exposeClass(InheritedAnnotationClass.class);
LuaTable exposedClasses = factory.getExposedClasses();
assertNotNull(exposedClasses);
Map exposed = manager.fromLuaToJava(exposedClasses, Map.class);
assertEquals(exposed.size(), 2);
assertNotNull(exposed.get(InheritedAnnotationClass.class.getName()));
assertNotNull(exposed.get(BaseAnnotationClass.class.getName()));
}
@Test
public void testConstructor() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
String testString = "s = NewBase(); assert(s:baseMethod2() == 'Base');";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
}
@Test
public void testDokuWikiOutput() {
factory.exposeClass(InheritedAnnotationClass.class);
ApiDocumentationExporter exporter = new ApiDocumentationExporter(factory.getClassDebugInformation());
StringWriter writer = new StringWriter();
DokuWikiPrinter printer = new DokuWikiPrinter(writer, exporter);
printer.process();
String output = writer.getBuffer().toString();
}
@Test
public void testVarargs() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
String testString = "foo = NewBase(); local s = foo:withVarargs('.', 'java', 'lang', 'String'); assert(s == 'java.lang.String')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
}
@Test
public void testVarargs2() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
String testString = "foo = NewBase(); local s = foo:withVarargs('.'); assert(s == '')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
state.call(closure, null);
}
@Test
public void testVarargsFail() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
String testString = "foo = NewBase(); local s = foo:withVarargs('.', {}); assert(s == '')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
try {
state.call(closure, null);
fail();
} catch (Exception e) {
assertEquals("No conversion found from class se.krka.kahlua.vm.LuaTableImpl to class java.lang.String at argument #2, strings", e.getMessage());
}
}
@Test
public void testVarargsFail2() throws IOException {
factory.exposeClass(InheritedAnnotationClass.class);
String testString = "foo = NewBase(); local s = foo:withVarargs(); assert(s == '')";
LuaClosure closure = LuaCompiler.loadstring(testString, "src", state.getEnvironment());
try {
state.call(closure, null);
fail();
} catch (Exception e) {
assertEquals("Expected 1 arguments but got 0. Correct syntax: obj:withVarargs(joinWith, strings)", e.getMessage());
}
}
}